Skip to content

Commit

Permalink
Add documentation to the DIT functions.
Browse files Browse the repository at this point in the history
- Also add documentation to the user on the use of the macro
and the functions.
- Enable the use of DIT flag in speed test via a command line option.
  • Loading branch information
nebeid committed Aug 6, 2024
1 parent eabffd0 commit d617845
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 8 deletions.
46 changes: 40 additions & 6 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ Both sets of tests may also be run with `ninja -C build run_tests`, but CMake

If your project is unable to take on a Go or Perl dependency, the AWS-LC repository
provides generated build files. These can be used in place of the files that would
normally be generated by these dependencies.
normally be generated by these dependencies.

It is still recommended to have both Go and Perl installed to be able to run the full
range of unit tests, as well as running valgrind and SDE tests. Building without Go now
Expand All @@ -228,12 +228,46 @@ More information on this can be found in [INCORPORATING.md](/INCORPORATING.md).

# Snapsafe Detection

AWS-LC supports Snapsafe-type uniqueness breaking event detection
on Linux using SysGenID (https://lkml.org/lkml/2021/3/8/677). This mechanism
is used for security hardening. If a SysGenID interface is not found, then the
mechanism is ignored.
AWS-LC supports Snapsafe-type uniqueness breaking event detection
on Linux using SysGenID (https://lkml.org/lkml/2021/3/8/677). This mechanism
is used for security hardening. If a SysGenID interface is not found, then the
mechanism is ignored.

## Snapsafe Prerequisites

Snapshots taken on active hosts can potentially be unsafe to use.
Snapshots taken on active hosts can potentially be unsafe to use.
See "Snapshot Safety Prerequisites" here: https://lkml.org/lkml/2021/3/8/677

# Data Independent Timing on AArch64

The Data Independent Timing (DIT) flag on Arm64 processors, when
enabled, ensures the following as per [Arm A-profile Architecture
Registers
Document](https://developer.arm.com/documentation/ddi0601/2023-12/AArch64-Registers/DIT--Data-Independent-Timing):
- The timing of every load and store instruction is insensitive to the
value of the data being loaded or stored.
- For certain data processing instructions, the instruction takes a
time which is independent of the data in the registers and the NZCV
flags.

It is also expected to disable the Data Memory-dependent Prefetcher
(DMP) feature of Apple M-series CPUs starting at M3 as per [this
article](https://appleinsider.com/articles/24/03/21/apple-silicon-vulnerability-leaks-encryption-keys-and-cant-be-patched-easily).

Building with the option `-DENABLE_DATA_INDEPENDENT_TIMING_AARCH64=ON`
will enable the macro `SET_DIT_AUTO_DISABLE`. This macro is present at
the entry of functions that process/load/store secret data to enable
the DIT flag and then set it to its original value on entry. With
this build option, there is an effect on performance that varies by
function and by processor architecture. The effect is mostly due to
enabling and disabling the DIT flag. If it remains enabled over many
calls, the effect can be largely mitigated. Hence, the macro can be
inserted in the caller's application at the beginning of the code
scope that makes repeated calls to AWS-LC cryptographic
functions. Alternatively, the functions `armv8_enable_dit` and
`armv8_restore_dit` can be placed at the beginning and the end of
the code section, respectively.
An example of that usage is present in the benchmarking function
`Speed()` in `tool/speed.cc` when the `-dit` option is used

./tool/bssl speed -dit
14 changes: 13 additions & 1 deletion include/openssl/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,22 @@ OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void);
#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS) && defined(MAKE_DIT_AVAILABLE)
// (TODO): See if we can detect the DIT capability in Windows environment

// armv8_enable_dit sets the DIT flag to 1 and returns its original value
// before it was called.
uint64_t armv8_enable_dit(void);
void armv8_restore_dit(volatile uint64_t *original_dit);

// armv8_restore_dit takes as input a value to restore the DIT flag to.
void armv8_restore_dit(volatile uint64_t *original_dit);

// SET_DIT_AUTO_DISABLE can be inserted in the caller's application at
// the beginning of the code section that makes repeated calls to AWS-LC functions.
// The flag will be automatically restored to its original value at the end of the
// scope.
// This can minimise the effect on performance of repeatedly setting and
// disabling DIT.
// Instead of the macro, the functions above can be used.
// An example of their usage is present in the benchmarking function
// `Speed()` in `tool/speed.cc` when the option `-dit` is passed in.
#define SET_DIT_AUTO_DISABLE \
volatile uint64_t _dit_restore_orig \
__attribute__((cleanup(armv8_restore_dit))) \
Expand Down
24 changes: 23 additions & 1 deletion tool/speed.cc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ static inline void *BM_memset(void *dst, int c, size_t n) {
// g_print_json is true if printed output is JSON formatted.
static bool g_print_json = false;

// g_dit is true if the DIT macro is to be enabled before benchmarking
static bool g_dit = false;

static std::string ChunkLenSuffix(size_t chunk_len) {
char buf[32];
snprintf(buf, sizeof(buf), " (%zu byte%s)", chunk_len,
Expand Down Expand Up @@ -2531,6 +2534,12 @@ static const argument_t kArguments[] = {
"there is no information about the bytes per call for an operation, "
"the JSON field for bytesPerCall will be omitted.",
},
{
"-dit",
kBooleanArgument,
"If this flag is set, the DIT flag is enabled before benchmarking and"
"disabled at the end."
},
{
"",
kOptionalArgument,
Expand Down Expand Up @@ -2584,7 +2593,6 @@ static bool parseStringVectorToIntegerVector(
}

bool Speed(const std::vector<std::string> &args) {
//SET_DIT_AUTO_DISABLE;
#if AWSLC_API_VERSION > 27
OPENSSL_BEGIN_ALLOW_DEPRECATED
// We started marking this as deprecated.
Expand All @@ -2607,6 +2615,10 @@ bool Speed(const std::vector<std::string> &args) {
}
}

if (args_map.count("-dit") != 0) {
g_dit = true;
}

if (args_map.count("-json") != 0) {
g_print_json = true;
}
Expand Down Expand Up @@ -2659,6 +2671,12 @@ bool Speed(const std::vector<std::string> &args) {
}
}

uint64_t original_dit = 0;
if (g_dit)
{
original_dit = armv8_enable_dit();
}

// kTLSADLen is the number of bytes of additional data that TLS passes to
// AEADs.
static const size_t kTLSADLen = 13;
Expand Down Expand Up @@ -2807,5 +2825,9 @@ bool Speed(const std::vector<std::string> &args) {
puts("\n]");
}

if (g_dit)
{
armv8_restore_dit(&original_dit);
}
return true;
}

0 comments on commit d617845

Please sign in to comment.