Skip to content

Commit

Permalink
Make DIT functions (enable/disable and set/reset) available regardles…
Browse files Browse the repository at this point in the history
…s of the build flag.
  • Loading branch information
nebeid committed Aug 23, 2024
1 parent d97599a commit 6266730
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 27 deletions.
20 changes: 12 additions & 8 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ See "Snapshot Safety Prerequisites" here: https://lkml.org/lkml/2021/3/8/677

# Data Independent Timing on AArch64

The functions described in this section are still experimental.

The Data Independent Timing (DIT) flag on Arm64 processors, when
enabled, ensures the following as per [Arm A-profile Architecture
Registers
Expand All @@ -265,15 +267,17 @@ 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 that are invoked by the macro,
Alternatively, the functions that are invoked in the macro,
`armv8_set_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.
beginning and the end of the code section, respectively. These
functions are available regardless whether the build flag is used or
not. 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

The DIT capability, which is checked in `OPENSSL_cpuid_setup` can be masked
out at runtime by calling `armv8_disable_dit`. This would result in having the
functions `armv8_set_dit` and `armv8_restore_dit` being a noop. It can be made
available again at runtime by calling `armv8_enable_dit`.
The DIT capability, which is checked in `OPENSSL_cpuid_setup` can be
masked out at runtime by calling `armv8_disable_dit`. This would
result in having the functions `armv8_set_dit` and `armv8_restore_dit`
being a noop. It can be made available again at runtime by calling
`armv8_enable_dit`.
4 changes: 2 additions & 2 deletions crypto/fipsmodule/cpucap/cpu_aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void handle_cpu_env(uint32_t *out, const char *in) {
}
}

#if defined(MAKE_DIT_AVAILABLE) && !defined(OPENSSL_WINDOWS)
#if !defined(OPENSSL_WINDOWS)
// "DIT" is not recognised as a register name by clang-10 (at least)
// Register's encoded name is from e.g.
// https://github.com/ashwio/arm64-sysreg-lib/blob/d421e249a026f6f14653cb6f9c4edd8c5d898595/include/sysreg/dit.h#L286
Expand Down Expand Up @@ -96,6 +96,6 @@ void armv8_enable_dit(void) {
OPENSSL_armcap_P |= ARMV8_DIT_ALLOWED;
}

#endif // MAKE_DIT_AVAILABLE && !OPENSSL_WINDOWS
#endif // !OPENSSL_WINDOWS

#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP
2 changes: 0 additions & 2 deletions crypto/fipsmodule/cpucap/cpu_aarch64_apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,9 @@ void OPENSSL_cpuid_setup(void) {
OPENSSL_armcap_P |= ARMV8_APPLE_M1;
}

#if defined(MAKE_DIT_AVAILABLE)
if (has_hw_feature("hw.optional.arm.FEAT_DIT")) {
OPENSSL_armcap_P |= (ARMV8_DIT | ARMV8_DIT_ALLOWED);
}
#endif // MAKE_DIT_AVAILABLE

// OPENSSL_armcap is a 32-bit, unsigned value which may start with "0x" to
// indicate a hex value. Prior to the 32-bit value, a '~' or '|' may be given.
Expand Down
2 changes: 0 additions & 2 deletions crypto/fipsmodule/cpucap/cpu_aarch64_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,11 @@ void OPENSSL_cpuid_setup(void) {
}
}

#if defined(MAKE_DIT_AVAILABLE)
static const unsigned long kDIT = 1 << 24;
// Before setting/resetting the DIT flag, check it's available in HWCAP
if (hwcap & kDIT) {
OPENSSL_armcap_P |= (ARMV8_DIT | ARMV8_DIT_ALLOWED);
}
#endif // MAKE_DIT_AVAILABLE

// OPENSSL_armcap is a 32-bit, unsigned value which may start with "0x" to
// indicate a hex value. Prior to the 32-bit value, a '~' or '|' may be given.
Expand Down
27 changes: 16 additions & 11 deletions include/openssl/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void);

// Data-Independent Timing (DIT) on AArch64

#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS) && defined(MAKE_DIT_AVAILABLE)
#if defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS)
// (TODO): See if we can detect the DIT capability in Windows environment

// armv8_set_dit sets the DIT flag to 1 and returns its original value
Expand All @@ -96,6 +96,17 @@ uint64_t armv8_set_dit(void);
// armv8_restore_dit takes as input a value to restore the DIT flag to.
void armv8_restore_dit(volatile uint64_t *original_dit);

// armv8_disable_dit is a run-time disabler of the DIT capability.
// It results in CRYPTO_is_ARMv8_DIT_capable() returning 0 even if the
// capability exists.
void armv8_disable_dit(void);

// armv8_enable_dit is a run-time enabler of the DIT capability. If
// |armv8_disable_dit| was used to disable the DIT capability, this function
// makes it available again.
void armv8_enable_dit(void);

#if defined(MAKE_DIT_AVAILABLE)
// 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
Expand All @@ -110,19 +121,13 @@ void armv8_restore_dit(volatile uint64_t *original_dit);
__attribute__((cleanup(armv8_restore_dit))) \
OPENSSL_UNUSED = armv8_set_dit();

// armv8_disable_dit is a run-time disabler of the DIT capability.
// It results in CRYPTO_is_ARMv8_DIT_capable() returning 0 even if the
// capability exists.
void armv8_disable_dit(void);

// armv8_enable_dit is a run-time enabler of the DIT capability. If
// |armv8_disable_dit| was used to disable the DIT capability, this function
// makes it available again.
void armv8_enable_dit(void);
#else
#define SET_DIT_AUTO_DISABLE
#endif // MAKE_DIT_AVAILABLE

#else
#define SET_DIT_AUTO_DISABLE
#endif // OPENSSL_AARCH64 && !OPENSSL_WINDOWS && MAKE_DIT_AVAILABLE
#endif // OPENSSL_AARCH64 && !OPENSSL_WINDOWS

// FIPS monitoring

Expand Down
3 changes: 1 addition & 2 deletions tool/speed.cc
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ static inline void *align_pointer(void *ptr, size_t alignment) {
}
#endif

#if defined(OPENSSL_IS_AWSLC) && defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS) && \
defined(MAKE_DIT_AVAILABLE)
#if defined(OPENSSL_IS_AWSLC) && defined(OPENSSL_AARCH64) && !defined(OPENSSL_WINDOWS)
#define DIT_OPTION
#endif

Expand Down

0 comments on commit 6266730

Please sign in to comment.