mirror of https://github.com/openssl/openssl.git
Merge 6c061c1c7f into a11b5ae0d2
This commit is contained in:
commit
5740236ed0
|
|
@ -218,6 +218,14 @@ _armv8_rng_probe:
|
|||
mrs x0, s3_3_c2_c4_1 // rndrrs
|
||||
ret
|
||||
.size _armv8_rng_probe,.-_armv8_rng_probe
|
||||
|
||||
.globl _armv8_dit_probe
|
||||
.type _armv8_dit_probe,%function
|
||||
_armv8_dit_probe:
|
||||
AARCH64_VALID_CALL_TARGET
|
||||
mrs x0, s3_3_c4_c2_5 // dit
|
||||
ret
|
||||
.size _armv8_dit_probe,.-_armv8_dit_probe
|
||||
___
|
||||
|
||||
sub gen_random {
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized;
|
|||
#define ARMV8_HAVE_SHA3_AND_WORTH_USING (1 << 15)
|
||||
#define ARMV8_UNROLL12_EOR3 (1 << 16)
|
||||
#define ARMV9_SVE2_POLY1305 (1 << 17)
|
||||
#define ARMV8_DIT (1 << 18)
|
||||
|
||||
/*
|
||||
* MIDR_EL1 system register
|
||||
|
|
|
|||
|
|
@ -142,6 +142,7 @@ static unsigned long getauxval(unsigned long key)
|
|||
#define OSSL_HWCAP_CE_SM4 (1 << 19)
|
||||
#define OSSL_HWCAP_CE_SHA512 (1 << 21)
|
||||
#define OSSL_HWCAP_SVE (1 << 22)
|
||||
#define OSSL_HWCAP_DIT (1 << 24)
|
||||
/* AT_HWCAP2 */
|
||||
#define OSSL_HWCAP2 26
|
||||
#define OSSL_HWCAP2_SVE2 (1 << 1)
|
||||
|
|
@ -217,6 +218,7 @@ void _armv8_eor3_probe(void);
|
|||
void _armv8_sve_probe(void);
|
||||
void _armv8_sve2_probe(void);
|
||||
void _armv8_rng_probe(void);
|
||||
void _armv8_dit_probe(void);
|
||||
#endif
|
||||
#endif /* !__APPLE__ && !OSSL_IMPLEMENT_GETAUXVAL */
|
||||
|
||||
|
|
@ -294,6 +296,7 @@ void OPENSSL_cpuid_setup(void)
|
|||
/* More recent extensions are indicated by sysctls */
|
||||
OPENSSL_armcap_P |= sysctl_query("hw.optional.armv8_2_sha512", ARMV8_SHA512);
|
||||
OPENSSL_armcap_P |= sysctl_query("hw.optional.armv8_2_sha3", ARMV8_SHA3);
|
||||
OPENSSL_armcap_P |= sysctl_query("hw.optional.arm.FEAT_DIT", ARMV8_DIT);
|
||||
|
||||
if (OPENSSL_armcap_P & ARMV8_SHA3) {
|
||||
char uarch[64];
|
||||
|
|
@ -346,6 +349,9 @@ void OPENSSL_cpuid_setup(void)
|
|||
if (getauxval(OSSL_HWCAP) & OSSL_HWCAP_SVE)
|
||||
OPENSSL_armcap_P |= ARMV8_SVE;
|
||||
|
||||
if (getauxval(OSSL_HWCAP) & OSSL_HWCAP_DIT)
|
||||
OPENSSL_armcap_P |= ARMV8_DIT;
|
||||
|
||||
if (getauxval(OSSL_HWCAP2) & OSSL_HWCAP2_SVE2)
|
||||
OPENSSL_armcap_P |= ARMV9_SVE2;
|
||||
|
||||
|
|
@ -394,6 +400,7 @@ void OPENSSL_cpuid_setup(void)
|
|||
OPENSSL_armcap_P |= arm_probe_for(_armv8_sve_probe, ARMV8_SVE);
|
||||
OPENSSL_armcap_P |= arm_probe_for(_armv8_sve2_probe, ARMV9_SVE2);
|
||||
OPENSSL_armcap_P |= arm_probe_for(_armv8_rng_probe, ARMV8_RNG);
|
||||
OPENSSL_armcap_P |= arm_probe_for(_armv8_dit_probe, ARMV8_DIT);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -434,3 +441,66 @@ void OPENSSL_cpuid_setup(void)
|
|||
#endif
|
||||
}
|
||||
#endif /* _WIN32, __ARM_MAX_ARCH__ >= 7 */
|
||||
|
||||
#if defined(__aarch64__) && !defined(OSSL_NO_DIT)
|
||||
|
||||
/* For PSTATE.DIT */
|
||||
|
||||
/* Gets the current value of the DIT flag as 0 or 1 */
|
||||
/* MUST NOT be called unless OPENSSL_armcap_P has ARMV8_DIT set */
|
||||
static ossl_inline uint64_t ossl_get_dit(void)
|
||||
{
|
||||
uint64_t val = 0;
|
||||
|
||||
/* In case we're used with an older assembler that doesn't understand DIT */
|
||||
__asm__ volatile("mrs %0, s3_3_c4_c2_5" : "=r"(val));
|
||||
|
||||
return (val >> 24) & 1;
|
||||
}
|
||||
|
||||
/* Sets DIT on: MUST NOT be called unless OPENSSL_armcap_P has ARMV8_DIT set */
|
||||
static ossl_inline void ossl_set_dit_on(void)
|
||||
{
|
||||
__asm__ volatile(".inst 0xD503415F"); /* msr dit, #1 */
|
||||
}
|
||||
|
||||
/* Sets DIT off: MUST NOT be called unless OPENSSL_armcap_P has ARMV8_DIT set */
|
||||
static ossl_inline void ossl_set_dit_off(void)
|
||||
{
|
||||
__asm__ volatile(".inst 0xD503405F"); /* msr dit, #0 */
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets DIT on and returns original value (0 or value given, for off and on respectively)
|
||||
* (we allow the caller to supply the "on" value returned, so that bit flags
|
||||
* can be supported more easily).
|
||||
*/
|
||||
int OPENSSL_ensure_dit_on(int value_for_on)
|
||||
{
|
||||
if (!(OPENSSL_armcap_P & ARMV8_DIT))
|
||||
return 0;
|
||||
|
||||
if (ossl_get_dit()) /* It's already enabled */
|
||||
return value_for_on; /* Tell caller to leave it on */
|
||||
|
||||
ossl_set_dit_on();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the DIT flag to its previous value, either off (*dit_prev == 0) or
|
||||
* on (*dit_prev != 0). To be called when DIT is already on.
|
||||
*/
|
||||
void OPENSSL_restore_original_dit(volatile int *dit_prev)
|
||||
{
|
||||
if (!(OPENSSL_armcap_P & ARMV8_DIT)) /* Nothing to do */
|
||||
return;
|
||||
|
||||
if (*dit_prev) /* Was previously set, so leave */
|
||||
return;
|
||||
|
||||
ossl_set_dit_off();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -5638,6 +5638,8 @@ int ossl_ed25519_sign(uint8_t *out_sig, const uint8_t *tbs, size_t tbs_len,
|
|||
unsigned int sz;
|
||||
int res = 0;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (context == NULL)
|
||||
context_len = 0;
|
||||
|
||||
|
|
@ -5699,6 +5701,8 @@ int ossl_ed25519_pubkey_verify(const uint8_t *pub, size_t pub_len)
|
|||
{
|
||||
ge_p3 A;
|
||||
|
||||
/* OSSL_ENABLE_DIT_FOR_SCOPE explicitly omitted on verify */
|
||||
|
||||
if (pub_len != ED25519_KEYLEN)
|
||||
return 0;
|
||||
return (ge_frombytes_vartime(&A, pub) == 0);
|
||||
|
|
@ -5820,6 +5824,8 @@ int ossl_ed25519_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[3
|
|||
int r;
|
||||
EVP_MD *sha512 = NULL;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
sha512 = EVP_MD_fetch(ctx, SN_sha512, propq);
|
||||
if (sha512 == NULL)
|
||||
return 0;
|
||||
|
|
@ -5845,6 +5851,9 @@ int ossl_x25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
|
|||
const uint8_t peer_public_value[32])
|
||||
{
|
||||
static const uint8_t kZeros[32] = { 0 };
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
x25519_scalar_mult(out_shared_key, private_key, peer_public_value);
|
||||
/* The all-zero output results when the input is a point of small order. */
|
||||
return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0;
|
||||
|
|
@ -5857,6 +5866,8 @@ void ossl_x25519_public_from_private(uint8_t out_public_value[32],
|
|||
ge_p3 A;
|
||||
fe zplusy, zminusy, zminusy_inv;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
memcpy(e, private_key, 32);
|
||||
e[0] &= 248;
|
||||
e[31] &= 127;
|
||||
|
|
|
|||
|
|
@ -216,6 +216,8 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
|
|
@ -259,6 +261,8 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
|
||||
return -2;
|
||||
|
|
|
|||
|
|
@ -744,6 +744,8 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||
size_t soutl, inl_ = (size_t)inl;
|
||||
int blocksize;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ossl_likely(outl != NULL)) {
|
||||
*outl = 0;
|
||||
} else {
|
||||
|
|
@ -805,6 +807,8 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
|||
size_t soutl;
|
||||
int blocksize;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (outl != NULL) {
|
||||
*outl = 0;
|
||||
} else {
|
||||
|
|
@ -855,6 +859,8 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
|||
size_t soutl, inl_ = (size_t)inl;
|
||||
int blocksize;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ossl_likely(outl != NULL)) {
|
||||
*outl = 0;
|
||||
} else {
|
||||
|
|
@ -911,6 +917,8 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
|||
int ret;
|
||||
int blocksize;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (outl != NULL) {
|
||||
*outl = 0;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -225,6 +225,8 @@ int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx,
|
|||
unsigned char *out, size_t *outlen,
|
||||
unsigned char *secret, size_t *secretlen)
|
||||
{
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
|
|
@ -262,6 +264,8 @@ int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx,
|
|||
unsigned char *secret, size_t *secretlen,
|
||||
const unsigned char *in, size_t inlen)
|
||||
{
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL
|
||||
|| (in == NULL || inlen == 0)
|
||||
|| (secret == NULL && secretlen == NULL))
|
||||
|
|
|
|||
|
|
@ -337,6 +337,8 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
|
|||
EVP_PKEY_CTX *pctx = ctx->pctx;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
|
||||
return 0;
|
||||
|
|
@ -412,6 +414,8 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
|
|||
int r = 0;
|
||||
EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
|
|
@ -465,6 +469,8 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
|
|||
return 0;
|
||||
}
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
|
||||
ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ int EVP_PKEY_generate(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
|
|||
/* Legacy compatible keygen callback info, only used with provider impls */
|
||||
int gentmp[2];
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ppkey == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
|
|||
|
|
@ -903,6 +903,8 @@ int EVP_PKEY_sign_message_update(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
|
|
@ -935,6 +937,8 @@ int EVP_PKEY_sign_message_final(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
|
|
@ -969,6 +973,8 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
|
|
@ -1051,6 +1057,8 @@ int EVP_PKEY_verify_message_update(EVP_PKEY_CTX *ctx,
|
|||
const char *desc;
|
||||
int ret;
|
||||
|
||||
/* OSSL_ENABLE_DIT_FOR_SCOPE explicitly omitted on verify */
|
||||
|
||||
if (ctx == NULL) {
|
||||
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -1683,9 +1683,10 @@ This call is only valid when decrypting data.
|
|||
Where possible the B<EVP> interface to symmetric ciphers should be used in
|
||||
preference to the low-level interfaces. This is because the code then becomes
|
||||
transparent to the cipher used and much more flexible. Additionally, the
|
||||
B<EVP> interface will ensure the use of platform specific cryptographic
|
||||
acceleration such as AES-NI (the low-level interfaces do not provide the
|
||||
guarantee).
|
||||
B<EVP> interface will ensure the use of platform-specific cryptographic
|
||||
acceleration such as AES-NI and platform-provided data-independent timing
|
||||
protection such as DIT (the low-level interfaces do not provide these
|
||||
guarantees).
|
||||
|
||||
PKCS padding works by adding B<n> padding bytes of value B<n> to make the total
|
||||
length of the encrypted data a multiple of the block size. Padding is always
|
||||
|
|
|
|||
|
|
@ -591,6 +591,53 @@ void OSSL_sleep(uint64_t millis);
|
|||
|
||||
void *OSSL_LIB_CTX_get_data(OSSL_LIB_CTX *ctx, int index);
|
||||
|
||||
/*
|
||||
* Data-independent timing.
|
||||
*
|
||||
* OSSL_ENABLE_DIT_FOR_SCOPE must be placed before code that uses instructions
|
||||
* whose timing depends on their data - otherwise constant-time code might not
|
||||
* be.
|
||||
*
|
||||
* OSSL_ENABLE_DIT_FOR_SCOPE can be placed at the beginning of a code section
|
||||
* that makes repeated calls to crypto functions.
|
||||
*
|
||||
* DIT state will automatically be restored to its previous value at the end of
|
||||
* the scope.
|
||||
*
|
||||
* This can reduce the overhead of repeatedly setting and resetting the state.
|
||||
*
|
||||
* Note that this requires the cleanup attribute to function, and that this
|
||||
* attribute is not supported in clang versions before 15. Support for the
|
||||
* cleanup attribute was introduced into GCC in version 4.0, which pre-dates
|
||||
* Aarch64. For the minute we just support those two compilers, but if a
|
||||
* compiler has attribute cleanup support, it could be added to the list below.
|
||||
*/
|
||||
|
||||
#if defined(__aarch64__) && !defined(OSSL_NO_DIT)
|
||||
#if !(defined(__GNUC__) || (defined(__clang__) && (__clang_major__ >= 15)))
|
||||
#warning "Unsupported compiler - disabling DIT"
|
||||
#define OSSL_NO_DIT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) && !defined(OSSL_NO_DIT)
|
||||
|
||||
/* Internal functions used by OSSL_ENABLE_DIT_FOR_SCOPE */
|
||||
void OPENSSL_restore_original_dit(volatile int *dit_prev);
|
||||
int OPENSSL_ensure_dit_on(int);
|
||||
|
||||
#define OSSL_ENABLE_DIT_FOR_SCOPE \
|
||||
volatile int dit_prev_ \
|
||||
__attribute__((cleanup(OPENSSL_restore_original_dit))) \
|
||||
__attribute__((unused)) \
|
||||
= OPENSSL_ensure_dit_on(1);
|
||||
|
||||
#else
|
||||
|
||||
#define OSSL_ENABLE_DIT_FOR_SCOPE
|
||||
|
||||
#endif /* __aarch64__ && !OSSL_NO_DIT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue