From 10b0447cc2da0008d2b7c3c5cbba5ed1310f079e Mon Sep 17 00:00:00 2001
From: "li.longjiang"
Date: Tue, 21 Mar 2023 10:20:23 +0800
Subject: [PATCH 1/2] Fix Timing Oracle in RSA decryption
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
ANBZ: #4550
commit 43d8f88511991533f53680a751e9326999a6a31f upstream
Fix Timing Oracle in RSA decryption
A timing based side channel exists in the OpenSSL RSA Decryption
implementation which could be sufficient to recover a plaintext across
a network in a Bleichenbacher style attack. To achieve a successful
decryption an attacker would have to be able to send a very large number
of trial messages for decryption. The vulnerability affects all RSA
padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
Patch written by Dmitry Belyavsky and Hubert Kario
CVE-2022-4304
Signed-off-by: Matt Caswell
Fixes:cve-2022-4304
Reviewed-by: Dmitry Belyavskiy
Reviewed-by: Tomas Mraz
Signed-off-by: 李龙江
---
openssl-1.1.1-cve-2022-4304-RSA-oracle.patch | 805 +++++++++++++++++++
openssl.spec | 9 +-
2 files changed, 813 insertions(+), 1 deletion(-)
create mode 100644 openssl-1.1.1-cve-2022-4304-RSA-oracle.patch
diff --git a/openssl-1.1.1-cve-2022-4304-RSA-oracle.patch b/openssl-1.1.1-cve-2022-4304-RSA-oracle.patch
new file mode 100644
index 0000000..9a888a6
--- /dev/null
+++ b/openssl-1.1.1-cve-2022-4304-RSA-oracle.patch
@@ -0,0 +1,805 @@
+From 43d8f88511991533f53680a751e9326999a6a31f Mon Sep 17 00:00:00 2001
+From: Matt Caswell
+Date: Fri, 20 Jan 2023 15:26:54 +0000
+Subject: [PATCH 1/6] Fix Timing Oracle in RSA decryption
+
+A timing based side channel exists in the OpenSSL RSA Decryption
+implementation which could be sufficient to recover a plaintext across
+a network in a Bleichenbacher style attack. To achieve a successful
+decryption an attacker would have to be able to send a very large number
+of trial messages for decryption. The vulnerability affects all RSA
+padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
+
+Patch written by Dmitry Belyavsky and Hubert Kario
+
+CVE-2022-4304
+
+Reviewed-by: Dmitry Belyavskiy
+Reviewed-by: Tomas Mraz
+---
+ crypto/bn/bn_blind.c | 14 -
+ crypto/bn/bn_err.c | 2 +
+ crypto/bn/bn_local.h | 14 +
+ crypto/bn/build.info | 3 +-
+ crypto/bn/rsa_sup_mul.c | 614 ++++++++++++++++++++++++++++++++++++++++
+ crypto/err/openssl.txt | 3 +-
+ crypto/rsa/rsa_ossl.c | 17 +-
+ include/crypto/bn.h | 5 +
+ include/openssl/bnerr.h | 1 +
+ 9 files changed, 653 insertions(+), 20 deletions(-)
+ create mode 100644 crypto/bn/rsa_sup_mul.c
+
+diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
+index 76fc7ebcff..6e9d239321 100644
+--- a/crypto/bn/bn_blind.c
++++ b/crypto/bn/bn_blind.c
+@@ -13,20 +13,6 @@
+
+ #define BN_BLINDING_COUNTER 32
+
+-struct bn_blinding_st {
+- BIGNUM *A;
+- BIGNUM *Ai;
+- BIGNUM *e;
+- BIGNUM *mod; /* just a reference */
+- CRYPTO_THREAD_ID tid;
+- int counter;
+- unsigned long flags;
+- BN_MONT_CTX *m_ctx;
+- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+- CRYPTO_RWLOCK *lock;
+-};
+-
+ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
+ {
+ BN_BLINDING *ret = NULL;
+diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c
+index dd87c152cf..3dd8d9a568 100644
+--- a/crypto/bn/bn_err.c
++++ b/crypto/bn/bn_err.c
+@@ -73,6 +73,8 @@ static const ERR_STRING_DATA BN_str_functs[] = {
+ {ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"},
+ {ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"},
+ {ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"},
++ {ERR_PACK(ERR_LIB_BN, BN_F_OSSL_BN_RSA_DO_UNBLIND, 0),
++ "ossl_bn_rsa_do_unblind"},
+ {0, NULL}
+ };
+
+diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h
+index 62a969b134..4d8cb64675 100644
+--- a/crypto/bn/bn_local.h
++++ b/crypto/bn/bn_local.h
+@@ -283,6 +283,20 @@ struct bn_gencb_st {
+ } cb;
+ };
+
++struct bn_blinding_st {
++ BIGNUM *A;
++ BIGNUM *Ai;
++ BIGNUM *e;
++ BIGNUM *mod; /* just a reference */
++ CRYPTO_THREAD_ID tid;
++ int counter;
++ unsigned long flags;
++ BN_MONT_CTX *m_ctx;
++ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
++ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
++ CRYPTO_RWLOCK *lock;
++};
++
+ /*-
+ * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
+ *
+diff --git a/crypto/bn/build.info b/crypto/bn/build.info
+index b9ed5322fa..c9fe2fdada 100644
+--- a/crypto/bn/build.info
++++ b/crypto/bn/build.info
+@@ -5,7 +5,8 @@ SOURCE[../../libcrypto]=\
+ bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \
+ {- $target{bn_asm_src} -} \
+ bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
+- bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c
++ bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c \
++ rsa_sup_mul.c
+
+ INCLUDE[bn_exp.o]=..
+
+diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c
+new file mode 100644
+index 0000000000..acafefd5fe
+--- /dev/null
++++ b/crypto/bn/rsa_sup_mul.c
+@@ -0,0 +1,614 @@
++#include
++#include
++#include
++#include
++#include
++#include
++#include
++#include "internal/numbers.h"
++#include "internal/constant_time.h"
++#include "bn_local.h"
++
++# if BN_BYTES == 8
++typedef uint64_t limb_t;
++# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
++/* nonstandard; implemented by gcc on 64-bit platforms */
++typedef __uint128_t limb2_t;
++# define HAVE_LIMB2_T
++# endif
++# define LIMB_BIT_SIZE 64
++# define LIMB_BYTE_SIZE 8
++# elif BN_BYTES == 4
++typedef uint32_t limb_t;
++typedef uint64_t limb2_t;
++# define LIMB_BIT_SIZE 32
++# define LIMB_BYTE_SIZE 4
++# define HAVE_LIMB2_T
++# else
++# error "Not supported"
++# endif
++
++/*
++ * For multiplication we're using schoolbook multiplication,
++ * so if we have two numbers, each with 6 "digits" (words)
++ * the multiplication is calculated as follows:
++ * A B C D E F
++ * x I J K L M N
++ * --------------
++ * N*F
++ * N*E
++ * N*D
++ * N*C
++ * N*B
++ * N*A
++ * M*F
++ * M*E
++ * M*D
++ * M*C
++ * M*B
++ * M*A
++ * L*F
++ * L*E
++ * L*D
++ * L*C
++ * L*B
++ * L*A
++ * K*F
++ * K*E
++ * K*D
++ * K*C
++ * K*B
++ * K*A
++ * J*F
++ * J*E
++ * J*D
++ * J*C
++ * J*B
++ * J*A
++ * I*F
++ * I*E
++ * I*D
++ * I*C
++ * I*B
++ * + I*A
++ * ==========================
++ * N*B N*D N*F
++ * + N*A N*C N*E
++ * + M*B M*D M*F
++ * + M*A M*C M*E
++ * + L*B L*D L*F
++ * + L*A L*C L*E
++ * + K*B K*D K*F
++ * + K*A K*C K*E
++ * + J*B J*D J*F
++ * + J*A J*C J*E
++ * + I*B I*D I*F
++ * + I*A I*C I*E
++ *
++ * 1+1 1+3 1+5
++ * 1+0 1+2 1+4
++ * 0+1 0+3 0+5
++ * 0+0 0+2 0+4
++ *
++ * 0 1 2 3 4 5 6
++ * which requires n^2 multiplications and 2n full length additions
++ * as we can keep every other result of limb multiplication in two separate
++ * limbs
++ */
++
++#if defined HAVE_LIMB2_T
++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
++{
++ limb2_t t;
++ /*
++ * this is idiomatic code to tell compiler to use the native mul
++ * those three lines will actually compile to single instruction
++ */
++
++ t = (limb2_t)a * b;
++ *hi = t >> LIMB_BIT_SIZE;
++ *lo = (limb_t)t;
++}
++#elif (BN_BYTES == 8) && (defined _MSC_VER)
++/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */
++#pragma intrinsic(_umul128)
++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
++{
++ *lo = _umul128(a, b, hi);
++}
++#else
++/*
++ * if the compiler doesn't have either a 128bit data type nor a "return
++ * high 64 bits of multiplication"
++ */
++static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
++{
++ limb_t a_low = (limb_t)(uint32_t)a;
++ limb_t a_hi = a >> 32;
++ limb_t b_low = (limb_t)(uint32_t)b;
++ limb_t b_hi = b >> 32;
++
++ limb_t p0 = a_low * b_low;
++ limb_t p1 = a_low * b_hi;
++ limb_t p2 = a_hi * b_low;
++ limb_t p3 = a_hi * b_hi;
++
++ uint32_t cy = (uint32_t)(((p0 >> 32) + (uint32_t)p1 + (uint32_t)p2) >> 32);
++
++ *lo = p0 + (p1 << 32) + (p2 << 32);
++ *hi = p3 + (p1 >> 32) + (p2 >> 32) + cy;
++}
++#endif
++
++/* add two limbs with carry in, return carry out */
++static ossl_inline limb_t _add_limb(limb_t *ret, limb_t a, limb_t b, limb_t carry)
++{
++ limb_t carry1, carry2, t;
++ /*
++ * `c = a + b; if (c < a)` is idiomatic code that makes compilers
++ * use add with carry on assembly level
++ */
++
++ *ret = a + carry;
++ if (*ret < a)
++ carry1 = 1;
++ else
++ carry1 = 0;
++
++ t = *ret;
++ *ret = t + b;
++ if (*ret < t)
++ carry2 = 1;
++ else
++ carry2 = 0;
++
++ return carry1 + carry2;
++}
++
++/*
++ * add two numbers of the same size, return overflow
++ *
++ * add a to b, place result in ret; all arrays need to be n limbs long
++ * return overflow from addition (0 or 1)
++ */
++static ossl_inline limb_t add(limb_t *ret, limb_t *a, limb_t *b, size_t n)
++{
++ limb_t c = 0;
++ ossl_ssize_t i;
++
++ for(i = n - 1; i > -1; i--)
++ c = _add_limb(&ret[i], a[i], b[i], c);
++
++ return c;
++}
++
++/*
++ * return number of limbs necessary for temporary values
++ * when multiplying numbers n limbs large
++ */
++static ossl_inline size_t mul_limb_numb(size_t n)
++{
++ return 2 * n * 2;
++}
++
++/*
++ * multiply two numbers of the same size
++ *
++ * multiply a by b, place result in ret; a and b need to be n limbs long
++ * ret needs to be 2*n limbs long, tmp needs to be mul_limb_numb(n) limbs
++ * long
++ */
++static void limb_mul(limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp)
++{
++ limb_t *r_odd, *r_even;
++ size_t i, j, k;
++
++ r_odd = tmp;
++ r_even = &tmp[2 * n];
++
++ memset(ret, 0, 2 * n * sizeof(limb_t));
++
++ for (i = 0; i < n; i++) {
++ for (k = 0; k < i + n + 1; k++) {
++ r_even[k] = 0;
++ r_odd[k] = 0;
++ }
++ for (j = 0; j < n; j++) {
++ /*
++ * place results from even and odd limbs in separate arrays so that
++ * we don't have to calculate overflow every time we get individual
++ * limb multiplication result
++ */
++ if (j % 2 == 0)
++ _mul_limb(&r_even[i + j], &r_even[i + j + 1], a[i], b[j]);
++ else
++ _mul_limb(&r_odd[i + j], &r_odd[i + j + 1], a[i], b[j]);
++ }
++ /*
++ * skip the least significant limbs when adding multiples of
++ * more significant limbs (they're zero anyway)
++ */
++ add(ret, ret, r_even, n + i + 1);
++ add(ret, ret, r_odd, n + i + 1);
++ }
++}
++
++/* modifies the value in place by performing a right shift by one bit */
++static ossl_inline void rshift1(limb_t *val, size_t n)
++{
++ limb_t shift_in = 0, shift_out = 0;
++ size_t i;
++
++ for (i = 0; i < n; i++) {
++ shift_out = val[i] & 1;
++ val[i] = shift_in << (LIMB_BIT_SIZE - 1) | (val[i] >> 1);
++ shift_in = shift_out;
++ }
++}
++
++/* extend the LSB of flag to all bits of limb */
++static ossl_inline limb_t mk_mask(limb_t flag)
++{
++ flag |= flag << 1;
++ flag |= flag << 2;
++ flag |= flag << 4;
++ flag |= flag << 8;
++ flag |= flag << 16;
++#if (LIMB_BYTE_SIZE == 8)
++ flag |= flag << 32;
++#endif
++ return flag;
++}
++
++/*
++ * copy from either a or b to ret based on flag
++ * when flag == 0, then copies from b
++ * when flag == 1, then copies from a
++ */
++static ossl_inline void cselect(limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n)
++{
++ /*
++ * would be more efficient with non volatile mask, but then gcc
++ * generates code with jumps
++ */
++ volatile limb_t mask;
++ size_t i;
++
++ mask = mk_mask(flag);
++ for (i = 0; i < n; i++) {
++#if (LIMB_BYTE_SIZE == 8)
++ ret[i] = constant_time_select_64(mask, a[i], b[i]);
++#else
++ ret[i] = constant_time_select_32(mask, a[i], b[i]);
++#endif
++ }
++}
++
++static limb_t _sub_limb(limb_t *ret, limb_t a, limb_t b, limb_t borrow)
++{
++ limb_t borrow1, borrow2, t;
++ /*
++ * while it doesn't look constant-time, this is idiomatic code
++ * to tell compilers to use the carry bit from subtraction
++ */
++
++ *ret = a - borrow;
++ if (*ret > a)
++ borrow1 = 1;
++ else
++ borrow1 = 0;
++
++ t = *ret;
++ *ret = t - b;
++ if (*ret > t)
++ borrow2 = 1;
++ else
++ borrow2 = 0;
++
++ return borrow1 + borrow2;
++}
++
++/*
++ * place the result of a - b into ret, return the borrow bit.
++ * All arrays need to be n limbs long
++ */
++static limb_t sub(limb_t *ret, limb_t *a, limb_t *b, size_t n)
++{
++ limb_t borrow = 0;
++ ossl_ssize_t i;
++
++ for (i = n - 1; i > -1; i--)
++ borrow = _sub_limb(&ret[i], a[i], b[i], borrow);
++
++ return borrow;
++}
++
++/* return the number of limbs necessary to allocate for the mod() tmp operand */
++static ossl_inline size_t mod_limb_numb(size_t anum, size_t modnum)
++{
++ return (anum + modnum) * 3;
++}
++
++/*
++ * calculate a % mod, place the result in ret
++ * size of a is defined by anum, size of ret and mod is modnum,
++ * size of tmp is returned by mod_limb_numb()
++ */
++static void mod(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
++ size_t modnum, limb_t *tmp)
++{
++ limb_t *atmp, *modtmp, *rettmp;
++ limb_t res;
++ size_t i;
++
++ memset(tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE);
++
++ atmp = tmp;
++ modtmp = &tmp[anum + modnum];
++ rettmp = &tmp[(anum + modnum) * 2];
++
++ for (i = modnum; i 0; i--, rp--) {
++ v = _mul_add_limb(rp, mod, modnum, rp[modnum - 1] * ni0, tmp2);
++ v = v + carry + rp[-1];
++ carry |= (v != rp[-1]);
++ carry &= (v <= rp[-1]);
++ rp[-1] = v;
++ }
++
++ /* perform the final reduction by mod... */
++ carry -= sub(ret, rp, mod, modnum);
++
++ /* ...conditionally */
++ cselect(carry, ret, rp, ret, modnum);
++}
++
++/* allocated buffer should be freed afterwards */
++static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs)
++{
++ int i;
++ int real_limbs = (BN_num_bytes(bn) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
++ limb_t *ptr = buf + (limbs - real_limbs);
++
++ for (i = 0; i < real_limbs; i++)
++ ptr[i] = bn->d[real_limbs - i - 1];
++}
++
++#if LIMB_BYTE_SIZE == 8
++static ossl_inline uint64_t be64(uint64_t host)
++{
++ const union {
++ long one;
++ char little;
++ } is_endian = { 1 };
++
++ if (is_endian.little) {
++ uint64_t big = 0;
++
++ big |= (host & 0xff00000000000000) >> 56;
++ big |= (host & 0x00ff000000000000) >> 40;
++ big |= (host & 0x0000ff0000000000) >> 24;
++ big |= (host & 0x000000ff00000000) >> 8;
++ big |= (host & 0x00000000ff000000) << 8;
++ big |= (host & 0x0000000000ff0000) << 24;
++ big |= (host & 0x000000000000ff00) << 40;
++ big |= (host & 0x00000000000000ff) << 56;
++ return big;
++ } else {
++ return host;
++ }
++}
++
++#else
++/* Not all platforms have htobe32(). */
++static ossl_inline uint32_t be32(uint32_t host)
++{
++ const union {
++ long one;
++ char little;
++ } is_endian = { 1 };
++
++ if (is_endian.little) {
++ uint32_t big = 0;
++
++ big |= (host & 0xff000000) >> 24;
++ big |= (host & 0x00ff0000) >> 8;
++ big |= (host & 0x0000ff00) << 8;
++ big |= (host & 0x000000ff) << 24;
++ return big;
++ } else {
++ return host;
++ }
++}
++#endif
++
++/*
++ * We assume that intermediate, possible_arg2, blinding, and ctx are used
++ * similar to BN_BLINDING_invert_ex() arguments.
++ * to_mod is RSA modulus.
++ * buf and num is the serialization buffer and its length.
++ *
++ * Here we use classic/Montgomery multiplication and modulo. After the calculation finished
++ * we serialize the new structure instead of BIGNUMs taking endianness into account.
++ */
++int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
++ const BN_BLINDING *blinding,
++ const BIGNUM *possible_arg2,
++ const BIGNUM *to_mod, BN_CTX *ctx,
++ unsigned char *buf, int num)
++{
++ limb_t *l_im = NULL, *l_mul = NULL, *l_mod = NULL;
++ limb_t *l_ret = NULL, *l_tmp = NULL, l_buf;
++ size_t l_im_count = 0, l_mul_count = 0, l_size = 0, l_mod_count = 0;
++ size_t l_tmp_count = 0;
++ int ret = 0;
++ size_t i;
++ unsigned char *tmp;
++ const BIGNUM *arg1 = intermediate;
++ const BIGNUM *arg2 = (possible_arg2 == NULL) ? blinding->Ai : possible_arg2;
++
++ l_im_count = (BN_num_bytes(arg1) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
++ l_mul_count = (BN_num_bytes(arg2) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
++ l_mod_count = (BN_num_bytes(to_mod) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
++
++ l_size = l_im_count > l_mul_count ? l_im_count : l_mul_count;
++ l_im = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
++ l_mul = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
++ l_mod = OPENSSL_zalloc(l_mod_count * LIMB_BYTE_SIZE);
++
++ if ((l_im == NULL) || (l_mul == NULL) || (l_mod == NULL))
++ goto err;
++
++ BN_to_limb(arg1, l_im, l_size);
++ BN_to_limb(arg2, l_mul, l_size);
++ BN_to_limb(to_mod, l_mod, l_mod_count);
++
++ l_ret = OPENSSL_malloc(2 * l_size * LIMB_BYTE_SIZE);
++
++ if (blinding->m_ctx != NULL) {
++ l_tmp_count = mul_limb_numb(l_size) > mod_montgomery_limb_numb(l_mod_count) ?
++ mul_limb_numb(l_size) : mod_montgomery_limb_numb(l_mod_count);
++ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
++ } else {
++ l_tmp_count = mul_limb_numb(l_size) > mod_limb_numb(2 * l_size, l_mod_count) ?
++ mul_limb_numb(l_size) : mod_limb_numb(2 * l_size, l_mod_count);
++ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
++ }
++
++ if ((l_ret == NULL) || (l_tmp == NULL))
++ goto err;
++
++ if (blinding->m_ctx != NULL) {
++ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
++ mod_montgomery(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count,
++ blinding->m_ctx->n0[0], l_tmp);
++ } else {
++ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
++ mod(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, l_tmp);
++ }
++
++ /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */
++ if (num < BN_num_bytes(to_mod)) {
++ BNerr(BN_F_OSSL_BN_RSA_DO_UNBLIND, ERR_R_PASSED_INVALID_ARGUMENT);
++ goto err;
++ }
++
++ memset(buf, 0, num);
++ tmp = buf + num - BN_num_bytes(to_mod);
++ for (i = 0; i < l_mod_count; i++) {
++#if LIMB_BYTE_SIZE == 8
++ l_buf = be64(l_ret[i]);
++#else
++ l_buf = be32(l_ret[i]);
++#endif
++ if (i == 0) {
++ int delta = LIMB_BYTE_SIZE - ((l_mod_count * LIMB_BYTE_SIZE) - num);
++
++ memcpy(tmp, ((char *)&l_buf) + LIMB_BYTE_SIZE - delta, delta);
++ tmp += delta;
++ } else {
++ memcpy(tmp, &l_buf, LIMB_BYTE_SIZE);
++ tmp += LIMB_BYTE_SIZE;
++ }
++ }
++ ret = num;
++
++ err:
++ OPENSSL_free(l_im);
++ OPENSSL_free(l_mul);
++ OPENSSL_free(l_mod);
++ OPENSSL_free(l_tmp);
++ OPENSSL_free(l_ret);
++
++ return ret;
++}
+diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
+index 9f91a4a811..ba3a46d5b9 100644
+--- a/crypto/err/openssl.txt
++++ b/crypto/err/openssl.txt
+@@ -1,4 +1,4 @@
+-# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
++# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
+ #
+ # Licensed under the OpenSSL license (the "License"). You may not use
+ # this file except in compliance with the License. You can obtain a copy
+@@ -232,6 +232,7 @@ BN_F_BN_RSHIFT:146:BN_rshift
+ BN_F_BN_SET_WORDS:144:bn_set_words
+ BN_F_BN_STACK_PUSH:148:BN_STACK_push
+ BN_F_BN_USUB:115:BN_usub
++BN_F_OSSL_BN_RSA_DO_UNBLIND:151:ossl_bn_rsa_do_unblind
+ BUF_F_BUF_MEM_GROW:100:BUF_MEM_grow
+ BUF_F_BUF_MEM_GROW_CLEAN:105:BUF_MEM_grow_clean
+ BUF_F_BUF_MEM_NEW:101:BUF_MEM_new
+diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c
+index b52a66f6a6..6c3c0cf78d 100644
+--- a/crypto/rsa/rsa_ossl.c
++++ b/crypto/rsa/rsa_ossl.c
+@@ -465,11 +465,20 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
+ BN_free(d);
+ }
+
+- if (blinding)
+- if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
++ if (blinding) {
++ /*
++ * ossl_bn_rsa_do_unblind() combines blinding inversion and
++ * 0-padded BN BE serialization
++ */
++ j = ossl_bn_rsa_do_unblind(ret, blinding, unblind, rsa->n, ctx,
++ buf, num);
++ if (j == 0)
+ goto err;
+-
+- j = BN_bn2binpad(ret, buf, num);
++ } else {
++ j = BN_bn2binpad(ret, buf, num);
++ if (j < 0)
++ goto err;
++ }
+
+ switch (padding) {
+ case RSA_PKCS1_PADDING:
+diff --git a/include/crypto/bn.h b/include/crypto/bn.h
+index 60afda1dad..b5f36fb25a 100644
+--- a/include/crypto/bn.h
++++ b/include/crypto/bn.h
+@@ -86,5 +86,10 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
+ int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
+ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+ const BIGNUM *d, BN_CTX *ctx);
++int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
++ const BN_BLINDING *blinding,
++ const BIGNUM *possible_arg2,
++ const BIGNUM *to_mod, BN_CTX *ctx,
++ unsigned char *buf, int num);
+
+ #endif
+diff --git a/include/openssl/bnerr.h b/include/openssl/bnerr.h
+index 9f3c7cfaab..a0752cea52 100644
+--- a/include/openssl/bnerr.h
++++ b/include/openssl/bnerr.h
+@@ -72,6 +72,7 @@ int ERR_load_BN_strings(void);
+ # define BN_F_BN_SET_WORDS 144
+ # define BN_F_BN_STACK_PUSH 148
+ # define BN_F_BN_USUB 115
++# define BN_F_OSSL_BN_RSA_DO_UNBLIND 151
+
+ /*
+ * BN reason codes.
+--
+2.39.1
+
diff --git a/openssl.spec b/openssl.spec
index 4d76f76..9fbb26d 100644
--- a/openssl.spec
+++ b/openssl.spec
@@ -23,7 +23,7 @@
Summary: Utilities from the general purpose cryptography library with TLS implementation
Name: openssl
Version: 1.1.1k
-Release: 7%{anolis_release}%{?dist}
+Release: 8%{anolis_release}%{?dist}
Epoch: 1
# We have to remove certain patented algorithms from the openssl source
# tarball with the hobble-openssl script which is included below.
@@ -90,6 +90,8 @@ Patch85: openssl-1.1.1-cve-2022-2068.patch
Patch86: openssl-1.1.1-cve-2022-2097.patch
# SM2 distid for sign and verify
Patch87: openssl-1.1.1-sm2-sign-verify.patch
+#OpenSSL 1.1.1t CVEs
+Patch101: openssl-1.1.1-cve-2022-4304-RSA-oracle.patc
License: OpenSSL and ASL 2.0
URL: http://www.openssl.org/
@@ -216,6 +218,7 @@ cp %{SOURCE13} test/
%patch85 -p1 -b .cve-2022-2068
%patch86 -p1 -b .cve-2022-2097
%patch87 -p1 -b .sm2-sign-verify
+%patch101 -p1 -b .cve-2022-4304
%build
# Figure out which flags we want to use.
@@ -504,6 +507,10 @@ export LD_LIBRARY_PATH
%postun libs -p /sbin/ldconfig
%changelog
+* Wed Feb 08 2023 Dmitry Belyavskiy - 1:1.1.1k-9
+- Fixed Timing Oracle in RSA Decryption
+ Resolves: CVE-2022-4304
+
* Mon Nov 28 2022 Tianjia Zhang - 1:1.1.1k-7.0.2
- Support SM2 distid for sign and verify
--
Gitee
From a905fe6e7ebb9ddd635f7b0f38e77a0dd90c8a84 Mon Sep 17 00:00:00 2001
From: "li.longjiang"
Date: Tue, 21 Mar 2023 13:08:52 +0000
Subject: [PATCH 2/2] update openssl.spec.
Signed-off-by: li.longjiang
---
openssl.spec | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/openssl.spec b/openssl.spec
index 9fbb26d..42aa76f 100644
--- a/openssl.spec
+++ b/openssl.spec
@@ -91,7 +91,7 @@ Patch86: openssl-1.1.1-cve-2022-2097.patch
# SM2 distid for sign and verify
Patch87: openssl-1.1.1-sm2-sign-verify.patch
#OpenSSL 1.1.1t CVEs
-Patch101: openssl-1.1.1-cve-2022-4304-RSA-oracle.patc
+Patch101: openssl-1.1.1-cve-2022-4304-RSA-oracle.patch
License: OpenSSL and ASL 2.0
URL: http://www.openssl.org/
--
Gitee