From d54aeb5a0f188331d0b81763fb049edab705a020 Mon Sep 17 00:00:00 2001 From: Clemens Lang Date: Fri, 9 Sep 2022 10:19:19 +0200 Subject: [PATCH] Fix AES-GCM on Power 8 CPUs Our backported patch unconditionally uses assembly instructions for Power9 and later, which triggers SIGILL on Power8 machines: | [ 3705.137658] sshd[1703]: illegal instruction (4) at 7fff85526aac nip 7fff85526aac lr 7fff854828e0 code 1 in libcrypto.so.3.0.5[7fff85240000+300000] Backport upstream's fix for this. Resolves: rhbz#2124845 Signed-off-by: Clemens Lang --- 0079-Fix-AES-GCM-on-Power-8-CPUs.patch | 146 +++++++++++++++++++++++++ openssl.spec | 9 +- 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 0079-Fix-AES-GCM-on-Power-8-CPUs.patch diff --git a/0079-Fix-AES-GCM-on-Power-8-CPUs.patch b/0079-Fix-AES-GCM-on-Power-8-CPUs.patch new file mode 100644 index 0000000..05c642e --- /dev/null +++ b/0079-Fix-AES-GCM-on-Power-8-CPUs.patch @@ -0,0 +1,146 @@ +From 5dee3e41a5b3f8934277de17a2ae192f43601948 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Fri, 9 Sep 2022 14:46:24 +0200 +Subject: [PATCH] Fix AES-GCM on Power 8 CPUs + +Properly fallback to the default implementation on CPUs +missing necessary instructions. + +Fixes #19163 + +(cherry picked from commit 24344d387178d45b37a1fbc51519c390e9a4effe) +--- + include/crypto/aes_platform.h | 12 +--- + .../ciphers/cipher_aes_gcm_hw_ppc.inc | 72 ++++++++++++++----- + 2 files changed, 56 insertions(+), 28 deletions(-) + +diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h +index 0c281a366a..6830bad0e9 100644 +--- a/include/crypto/aes_platform.h ++++ b/include/crypto/aes_platform.h +@@ -83,16 +83,8 @@ size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, + size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, unsigned char ivec[16], + u64 *Xi); +-size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out, +- size_t len, const void *key, +- unsigned char ivec[16], u64 *Xi); +-size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out, +- size_t len, const void *key, +- unsigned char ivec[16], u64 *Xi); +-# define AES_gcm_encrypt ppc_aes_gcm_encrypt_wrap +-# define AES_gcm_decrypt ppc_aes_gcm_decrypt_wrap +-# define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_p8_ctr32_encrypt_blocks && \ +- (gctx)->gcm.ghash==gcm_ghash_p8) ++# define AES_GCM_ASM_PPC(gctx) ((gctx)->ctr==aes_p8_ctr32_encrypt_blocks && \ ++ (gctx)->gcm.ghash==gcm_ghash_p8) + void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); + # endif /* PPC */ + +diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc +index 4eed0f4ab0..03e3eddc41 100644 +--- a/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc ++++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc +@@ -23,12 +23,6 @@ static int aes_ppc_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, + return 1; + } + +- +-extern size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, +- const void *key, unsigned char ivec[16], u64 *Xi); +-extern size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, +- const void *key, unsigned char ivec[16], u64 *Xi); +- + static inline u32 UTO32(unsigned char *buf) + { + return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | ((u32) buf[2] << 8) | ((u32) buf[3]); +@@ -47,7 +41,7 @@ static inline u32 add32TOU(unsigned char buf[4], u32 n) + return r; + } + +-static size_t aes_p10_gcm_crypt(const unsigned char *in, unsigned char *out, size_t len, ++static size_t ppc_aes_gcm_crypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi, int encrypt) + { + int s = 0; +@@ -90,24 +84,66 @@ static size_t aes_p10_gcm_crypt(const unsigned char *in, unsigned char *out, siz + return ndone; + } + +-size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out, size_t len, +- const void *key, unsigned char ivec[16], u64 *Xi) +-{ +- return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 1); +-} +- +-size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out, size_t len, +- const void *key, unsigned char ivec[16], u64 *Xi) ++static int ppc_aes_gcm_cipher_update(PROV_GCM_CTX *ctx, const unsigned char *in, ++ size_t len, unsigned char *out) + { +- return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 0); ++ if (ctx->enc) { ++ if (ctx->ctr != NULL) { ++ size_t bulk = 0; ++ ++ if (len >= AES_GCM_ENC_BYTES && AES_GCM_ASM_PPC(ctx)) { ++ size_t res = (16 - ctx->gcm.mres) % 16; ++ ++ if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, res)) ++ return 0; ++ ++ bulk = ppc_aes_gcm_crypt(in + res, out + res, len - res, ++ ctx->gcm.key, ++ ctx->gcm.Yi.c, ctx->gcm.Xi.u, 1); ++ ++ ctx->gcm.len.u[1] += bulk; ++ bulk += res; ++ } ++ if (CRYPTO_gcm128_encrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, ++ len - bulk, ctx->ctr)) ++ return 0; ++ } else { ++ if (CRYPTO_gcm128_encrypt(&ctx->gcm, in, out, len)) ++ return 0; ++ } ++ } else { ++ if (ctx->ctr != NULL) { ++ size_t bulk = 0; ++ ++ if (len >= AES_GCM_DEC_BYTES && AES_GCM_ASM_PPC(ctx)) { ++ size_t res = (16 - ctx->gcm.mres) % 16; ++ ++ if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, res)) ++ return -1; ++ ++ bulk = ppc_aes_gcm_crypt(in + res, out + res, len - res, ++ ctx->gcm.key, ++ ctx->gcm.Yi.c, ctx->gcm.Xi.u, 0); ++ ++ ctx->gcm.len.u[1] += bulk; ++ bulk += res; ++ } ++ if (CRYPTO_gcm128_decrypt_ctr32(&ctx->gcm, in + bulk, out + bulk, ++ len - bulk, ctx->ctr)) ++ return 0; ++ } else { ++ if (CRYPTO_gcm128_decrypt(&ctx->gcm, in, out, len)) ++ return 0; ++ } ++ } ++ return 1; + } + +- + static const PROV_GCM_HW aes_ppc_gcm = { + aes_ppc_gcm_initkey, + ossl_gcm_setiv, + ossl_gcm_aad_update, +- generic_aes_gcm_cipher_update, ++ ppc_aes_gcm_cipher_update, + ossl_gcm_cipher_final, + ossl_gcm_one_shot + }; +-- +2.37.3 + diff --git a/openssl.spec b/openssl.spec index 5c449d8..a3a10f9 100644 --- a/openssl.spec +++ b/openssl.spec @@ -29,7 +29,7 @@ print(string.sub(hash, 0, 16)) Summary: Utilities from the general purpose cryptography library with TLS implementation Name: openssl Version: 3.0.5 -Release: 3%{?dist} +Release: 4%{?dist} Epoch: 1 # We have to remove certain patented algorithms from the openssl source # tarball with the hobble-openssl script which is included below. @@ -159,6 +159,7 @@ Patch62: 0062-fips-Expose-a-FIPS-indicator.patch # Patch70: 0070-EVP_PKEY_Q_keygen-Call-OPENSSL_init_crypto-to-init-s.patch # https://github.com/openssl/openssl/commit/44a563dde1584cd9284e80b6e45ee5019be8d36c # https://github.com/openssl/openssl/commit/345c99b6654b8313c792d54f829943068911ddbd +# Regression on Power8, see rhbz2124845, https://github.com/openssl/openssl/issues/19163; fix in 0079-Fix-AES-GCM-on-Power-8-CPUs.patch Patch71: 0071-AES-GCM-performance-optimization.patch # https://github.com/openssl/openssl/commit/f596bbe4da779b56eea34d96168b557d78e1149 # https://github.com/openssl/openssl/commit/7e1f3ffcc5bc15fb9a12b9e3bb202f544c6ed5aa @@ -177,6 +178,8 @@ Patch76: 0076-FIPS-140-3-DRBG.patch Patch77: 0077-FIPS-140-3-zeroization.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2114772 Patch78: 0078-Add-FIPS-indicator-parameter-to-HKDF.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2124845, https://github.com/openssl/openssl/pull/19182 +Patch79: 0079-Fix-AES-GCM-on-Power-8-CPUs.patch License: ASL 2.0 URL: http://www.openssl.org/ @@ -514,6 +517,10 @@ install -m644 %{SOURCE9} \ %ldconfig_scriptlets libs %changelog +* Fri Sep 09 2022 Clemens Lang - 1:3.0.5-4 +- Fix AES-GCM on Power 8 CPUs + Resolves: rhbz#2124845 + * Thu Sep 01 2022 Dmitry Belyavskiy - 1:3.0.5-3 - Sync patches with RHEL Related: rhbz#2123755