The C11 change has survived for three months now. Let's start freely
using static_assert. In C files, we need to include <assert.h> because
it is a macro. In C++ files, it is a keyword and we can just use it. (In
MSVC C, it is actually also a keyword as in C++, but close enough.)
I moved one assert from ssl3.h to ssl_lib.cc. We haven't yet required
C11 in our public headers, just our internal files.
Change-Id: Ic59978be43b699f2c997858179a9691606784ea5
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53665
Auto-Submit: David Benjamin <davidben@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
I don't think these are all UB by C's rules, but it's easier not to
think about the pointers. Still more to go, but these were some easy
ones.
Bug: 301
Change-Id: Icdcb7fb40f85983cbf566786c5f7dbfd7bb06571
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/52905
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Bob Beck <bbe@google.com>
On Arm, our CRYPTO_is_*_capable functions check the corresponding
preprocessor symbol. This allows us to automatically drop dynamic checks
and fallback code when some capability is always avilable.
This CL does the same on x86, as well as consolidates our
OPENSSL_ia32cap_P checks in one place. Since this abstraction is
incompatible with some optimizations we do around OPENSSL_ia32cap_get()
in the FIPS module, I've marked the symbol __attribute__((const)), which
is enough to make GCC and Clang do the optimizations for us. (We already
do the same to DEFINE_BSS_GET.)
Most x86 platforms support a much wider range of capabilities, so this
is usually a no-op. But, notably, all x86_64 Mac hardware has SSSE3
available, so this allows us to statically drop an AES implementation.
(On macOS with -Wl,-dead_strip, this seems to trim 35080 bytes from the
bssl binary.) Configs like -march=native can also drop a bunch of code.
Update-Note: This CL may break build environments that incorrectly mark
some instruction as statically available. This is unlikely to happen
with vector instructions like AVX, where the compiler could freely emit
them anyway. However, instructions like AES-NI might be set incorrectly.
Change-Id: I44fd715c9887d3fda7cb4519c03bee4d4f2c7ea6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51548
Reviewed-by: Adam Langley <agl@google.com>
GCC's __ARMEL__ and __ARMEB__ defines denote little- and big-endian arm,
respectively. They are not defined on aarch64, which instead use
__AARCH64EL__ and __AARCH64EB__.
However, OpenSSL's assembly originally used the 32-bit defines on both
platforms and even define __ARMEL__ and __ARMEB__ in arm_arch.h. This is
less portable and can even interfere with other headers, which use
__ARMEL__ to detect little-endian arm. (Our own base.h believes
__ARMEL__ implies 32-bit arm. We just happen to check __AARCH64EL__
first. base.h is probably also always included before arm_arch.h.)
Over time, the aarch64 assembly has switched to the correct defines,
such as in 32bbb62ea634239e7cb91d6450ba23517082bab6. This commit
finishes the job.
(There is an even more official endianness detector, __ARM_BIG_ENDIAN in
the Arm C Language Extensions. But I've stuck with the GCC ones here as
that would be a larger change.)
See also https://github.com/openssl/openssl/pull/17373
Change-Id: Ic04ff85782e6599cdeaeb33d12c2fa8edc882224
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50848
Reviewed-by: Adam Langley <agl@google.com>
These symbols were not marked OPENSSL_EXPORT, so they weren't really
usable externally anyway. They're also very sensitive to various build
configuration toggles, which don't always get reflected into projects
that include our headers. Move them to crypto/internal.h.
Change-Id: I79a1fcf0b24e398d75a9cc6473bae28ec85cb835
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/50846
Reviewed-by: Adam Langley <agl@google.com>
This syncs this file up to e7ff223a20697e5a401d2d9bb7a75e699ed46633 from
upstream's OpenSSL_1_1_1-stable branch. The main change of note is the
4x loop from upstream's 7ff2fa4b9281232f0ca1db03d42a954c462ef77d,
9ee020f8dc7813db82a119058d8f57e70e7e8904,
aa7bf316980259a11dcbaf6128ed86d33dc24b97, and
603ebe03529101424670051aa0c616dc6e037b28.
Benchmarks on a Pixel 4a.
Before:
Did 14069000 AES-128-GCM (16 bytes) seal operations in 2000042us (112.5 MB/sec)
Did 6768000 AES-128-GCM (256 bytes) seal operations in 2000182us (866.2 MB/sec)
Did 1902000 AES-128-GCM (1350 bytes) seal operations in 2000479us (1283.5 MB/sec)
Did 359000 AES-128-GCM (8192 bytes) seal operations in 2003942us (1467.6 MB/sec)
Did 182000 AES-128-GCM (16384 bytes) seal operations in 2002245us (1489.3 MB/sec)
Did 13388000 AES-256-GCM (16 bytes) seal operations in 2000144us (107.1 MB/sec)
Did 6069000 AES-256-GCM (256 bytes) seal operations in 2000276us (776.7 MB/sec)
Did 1638000 AES-256-GCM (1350 bytes) seal operations in 2001076us (1105.1 MB/sec)
Did 305000 AES-256-GCM (8192 bytes) seal operations in 2000040us (1249.3 MB/sec)
Did 155000 AES-256-GCM (16384 bytes) seal operations in 2009398us (1263.8 MB/sec)
After:
Did 13837000 AES-128-GCM (16 bytes) seal operations in 2000131us (110.7 MB/sec) [-1.7%]
Did 7506000 AES-128-GCM (256 bytes) seal operations in 2000197us (960.7 MB/sec) [+10.9%]
Did 2289000 AES-128-GCM (1350 bytes) seal operations in 2000734us (1544.5 MB/sec) [+20.3%]
Did 443000 AES-128-GCM (8192 bytes) seal operations in 2000321us (1814.2 MB/sec) [+23.6%]
Did 225000 AES-128-GCM (16384 bytes) seal operations in 2002308us (1841.1 MB/sec) [+23.6%]
Did 13280000 AES-256-GCM (16 bytes) seal operations in 2000011us (106.2 MB/sec) [-0.8%]
Did 6630000 AES-256-GCM (256 bytes) seal operations in 2000229us (848.5 MB/sec) [+9.2%]
Did 1916000 AES-256-GCM (1350 bytes) seal operations in 2000373us (1293.1 MB/sec) [+17.0%]
Did 365000 AES-256-GCM (8192 bytes) seal operations in 2001519us (1493.9 MB/sec) [+19.6%]
Did 185000 AES-256-GCM (16384 bytes) seal operations in 2006588us (1510.5 MB/sec) [+19.5%]
(See cl/387919990 for some notes I made in reviewing, though likely
future me will find them incomprehensible anyway.)
Change-Id: Id386e80143611487e07b2fbfda15d0abc54ea145
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/48726
Reviewed-by: Adam Langley <agl@google.com>
Because file names are not enclosed in quotation marks in the open call.
https://bugs.chromium.org/p/boringssl/issues/detail?id=415
```
cmake --build "C:\Projects\ Extern\Visual C++ 2015\x64 Debug\Build\BoringSSL\."
[9/439] Generating rdrand-x86_64.asm
FAILED: crypto/fipsmodule/rdrand-x86_64.asm
cmd.exe /C "cd /D "C:\Projects\ Extern\Visual C++ 2015\x64 Debug\Build\BoringSSL\crypto\fipsmodule" && "C:\Program Files\CMake\bin\cmake.exe" -E make_directory . && C:\Perl64\bin\perl.exe "C:/Projects/ Extern/Source/BoringSSL/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl" nasm rdrand-x86_64.asm"
Can't open perl script "C:/Projects/": No such file or directory
error closing STDOUT at C:/Projects/ Extern/Source/BoringSSL/crypto/fipsmodule/rand/asm/rdrand-x86_64.pl line 87.
ninja: build stopped: subcommand failed.
```
Bug: 415
Change-Id: I83c4a460689b9adeb439425ad390322ae8b2002a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/47884
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
We have loads of variations of these. Align them in one set. This avoids
the HOST_* macros defined by md32_common.h, so it'll be a little easier
to make it a more conventional header.
Change-Id: Id47fe7b51a8f961bd87839f8146d8a5aa8027aa6
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46425
Reviewed-by: Adam Langley <agl@google.com>
It's a little confusing to have load_word_le but actually use size_t
instead of crypto_word_t.
NOTE: on some platforms, notably NaCl, crypto_word_t is larger than
size_t. (Do we still need to support this?) We don't have a good testing
story here, so I tested it by hacking up a 32-bit x86 build to think it
was OPENSSL_64_BIT.
Change-Id: Ia0ce469e86803f22655fe2d9659a6a5db766429f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46424
Reviewed-by: Adam Langley <agl@google.com>
See also 8129ac6ac4c0ca3a488c225cde580ede7dabe874 and
81198bf323ea9deda907714170d329ca7d2ff01f from upstream.
In trying to figure out why ASan (which normally catches overlapping
memcpys) didn't flag this, I noticed that we actually don't have tests
for empty inputs. I've added them to cipher_tests.txt where missing and
fixed a bad assert in ofb.c.
ASan still doesn't flag this because LLVM even requires memcpy handle
dst == src. Still, fixing it is less effort than getting a clear answer
from GCC and MSVC. Though this puts us in the frustrating position of
trying to follow a C rule that our main toolchain and sanitizer disavow.
https://bugs.llvm.org/show_bug.cgi?id=11763https://reviews.llvm.org/D86993
Change-Id: I53c64a84834ddf5cddca0b3d53a29998f666ea2f
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/46285
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
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-modelshttps://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 negligble.
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
Change-Id: I4335f92e2ccc8e209c7d68a0a79f1acdf3aeb791
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/42084
Reviewed-by: Adam Langley <agl@google.com>
Commit-Queue: Adam Langley <agl@google.com>