forked from mindspore-Ecosystem/mindspore
Fix OpenSSL CVE
This commit is contained in:
parent
43ffa26a3a
commit
992565da9d
|
@ -33,6 +33,10 @@ if(BUILD_LITE)
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4304.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4450.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0215.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0286.patch
|
||||||
)
|
)
|
||||||
elseif(PLATFORM_ARM32 AND ANDROID_NDK_TOOLCHAIN_INCLUDED)
|
elseif(PLATFORM_ARM32 AND ANDROID_NDK_TOOLCHAIN_INCLUDED)
|
||||||
set(openssl_USE_STATIC_LIBS OFF)
|
set(openssl_USE_STATIC_LIBS OFF)
|
||||||
|
@ -54,6 +58,10 @@ if(BUILD_LITE)
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4304.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4450.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0215.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0286.patch
|
||||||
)
|
)
|
||||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR APPLE)
|
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR APPLE)
|
||||||
set(openssl_CFLAGS -fvisibility=hidden)
|
set(openssl_CFLAGS -fvisibility=hidden)
|
||||||
|
@ -70,6 +78,10 @@ if(BUILD_LITE)
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4304.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4450.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0215.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0286.patch
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
MESSAGE(FATAL_ERROR "openssl does not support compilation for the current environment.")
|
MESSAGE(FATAL_ERROR "openssl does not support compilation for the current environment.")
|
||||||
|
@ -93,6 +105,10 @@ else()
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-1292.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2068.patch
|
||||||
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-2097.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4304.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2022-4450.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0215.patch
|
||||||
|
PATCHES ${OPENSSL_PATCH_ROOT}/CVE-2023-0286.patch
|
||||||
)
|
)
|
||||||
include_directories(${openssl_INC})
|
include_directories(${openssl_INC})
|
||||||
add_library(mindspore::ssl ALIAS openssl::ssl)
|
add_library(mindspore::ssl ALIAS openssl::ssl)
|
||||||
|
|
|
@ -0,0 +1,771 @@
|
||||||
|
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 <openssl/e_os2.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <openssl/bn.h>
|
||||||
|
+#include <openssl/err.h>
|
||||||
|
+#include <openssl/rsaerr.h>
|
||||||
|
+#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 <modnum + anum; i++)
|
||||||
|
+ atmp[i] = a[i-modnum];
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < modnum; i++)
|
||||||
|
+ modtmp[i] = mod[i];
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < anum * LIMB_BIT_SIZE; i++) {
|
||||||
|
+ rshift1(modtmp, anum + modnum);
|
||||||
|
+ res = sub(rettmp, atmp, modtmp, anum+modnum);
|
||||||
|
+ cselect(res, atmp, atmp, rettmp, anum+modnum);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ memcpy(ret, &atmp[anum], sizeof(limb_t) * modnum);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* necessary size of tmp for a _mul_add_limb() call with provided anum */
|
||||||
|
+static ossl_inline size_t _mul_add_limb_numb(size_t anum)
|
||||||
|
+{
|
||||||
|
+ return 2 * (anum + 1);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* multiply a by m, add to ret, return carry */
|
||||||
|
+static limb_t _mul_add_limb(limb_t *ret, limb_t *a, size_t anum,
|
||||||
|
+ limb_t m, limb_t *tmp)
|
||||||
|
+{
|
||||||
|
+ limb_t carry = 0;
|
||||||
|
+ limb_t *r_odd, *r_even;
|
||||||
|
+ size_t i;
|
||||||
|
+
|
||||||
|
+ memset(tmp, 0, sizeof(limb_t) * (anum + 1) * 2);
|
||||||
|
+
|
||||||
|
+ r_odd = tmp;
|
||||||
|
+ r_even = &tmp[anum + 1];
|
||||||
|
+
|
||||||
|
+ for (i = 0; i < anum; i++) {
|
||||||
|
+ /*
|
||||||
|
+ * place the results from even and odd limbs in separate arrays
|
||||||
|
+ * so that we have to worry about carry just once
|
||||||
|
+ */
|
||||||
|
+ if (i % 2 == 0)
|
||||||
|
+ _mul_limb(&r_even[i], &r_even[i + 1], a[i], m);
|
||||||
|
+ else
|
||||||
|
+ _mul_limb(&r_odd[i], &r_odd[i + 1], a[i], m);
|
||||||
|
+ }
|
||||||
|
+ /* assert: add() carry here will be equal zero */
|
||||||
|
+ add(r_even, r_even, r_odd, anum + 1);
|
||||||
|
+ /*
|
||||||
|
+ * while here it will not overflow as the max value from multiplication
|
||||||
|
+ * is -2 while max overflow from addition is 1, so the max value of
|
||||||
|
+ * carry is -1 (i.e. max int)
|
||||||
|
+ */
|
||||||
|
+ carry = add(ret, ret, &r_even[1], anum) + r_even[0];
|
||||||
|
+
|
||||||
|
+ return carry;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static ossl_inline size_t mod_montgomery_limb_numb(size_t modnum)
|
||||||
|
+{
|
||||||
|
+ return modnum * 2 + _mul_add_limb_numb(modnum);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * calculate a % mod, place result in ret
|
||||||
|
+ * assumes that a is in Montgomery form with the R (Montgomery modulus) being
|
||||||
|
+ * smallest power of two big enough to fit mod and that's also a power
|
||||||
|
+ * of the count of number of bits in limb_t (B).
|
||||||
|
+ * For calculation, we also need n', such that mod * n' == -1 mod B.
|
||||||
|
+ * anum must be <= 2 * modnum
|
||||||
|
+ * ret needs to be modnum words long
|
||||||
|
+ * tmp needs to be mod_montgomery_limb_numb(modnum) limbs long
|
||||||
|
+ */
|
||||||
|
+static void mod_montgomery(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
|
||||||
|
+ size_t modnum, limb_t ni0, limb_t *tmp)
|
||||||
|
+{
|
||||||
|
+ limb_t carry, v;
|
||||||
|
+ limb_t *res, *rp, *tmp2;
|
||||||
|
+ ossl_ssize_t i;
|
||||||
|
+
|
||||||
|
+ res = tmp;
|
||||||
|
+ /*
|
||||||
|
+ * for intermediate result we need an integer twice as long as modulus
|
||||||
|
+ * but keep the input in the least significant limbs
|
||||||
|
+ */
|
||||||
|
+ memset(res, 0, sizeof(limb_t) * (modnum * 2));
|
||||||
|
+ memcpy(&res[modnum * 2 - anum], a, sizeof(limb_t) * anum);
|
||||||
|
+ rp = &res[modnum];
|
||||||
|
+ tmp2 = &res[modnum * 2];
|
||||||
|
+
|
||||||
|
+ carry = 0;
|
||||||
|
+
|
||||||
|
+ /* add multiples of the modulus to the value until R divides it cleanly */
|
||||||
|
+ 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.
|
|
@ -0,0 +1,14 @@
|
||||||
|
diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c
|
||||||
|
index d416d939ea..328c30cdbb 100644
|
||||||
|
--- a/crypto/pem/pem_lib.c
|
||||||
|
+++ b/crypto/pem/pem_lib.c
|
||||||
|
@@ -957,7 +957,9 @@ int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
|
||||||
|
*data = pem_malloc(len, flags);
|
||||||
|
if (*header == NULL || *data == NULL) {
|
||||||
|
pem_free(*header, flags, 0);
|
||||||
|
+ *header = NULL;
|
||||||
|
pem_free(*data, flags, 0);
|
||||||
|
+ *data = NULL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
BIO_read(headerB, *header, headerlen);
|
|
@ -0,0 +1,144 @@
|
||||||
|
diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c
|
||||||
|
index 760e4846a4..f8d4b1b9aa 100644
|
||||||
|
--- a/crypto/asn1/bio_ndef.c
|
||||||
|
+++ b/crypto/asn1/bio_ndef.c
|
||||||
|
@@ -49,12 +49,19 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||||
|
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||||
|
void *parg);
|
||||||
|
|
||||||
|
+/*
|
||||||
|
+ * On success, the returned BIO owns the input BIO as part of its BIO chain.
|
||||||
|
+ * On failure, NULL is returned and the input BIO is owned by the caller.
|
||||||
|
+ *
|
||||||
|
+ * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream()
|
||||||
|
+ */
|
||||||
|
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||||
|
{
|
||||||
|
NDEF_SUPPORT *ndef_aux = NULL;
|
||||||
|
BIO *asn_bio = NULL;
|
||||||
|
const ASN1_AUX *aux = it->funcs;
|
||||||
|
ASN1_STREAM_ARG sarg;
|
||||||
|
+ BIO *pop_bio = NULL;
|
||||||
|
|
||||||
|
if (!aux || !aux->asn1_cb) {
|
||||||
|
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||||
|
@@ -69,21 +76,39 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||||
|
out = BIO_push(asn_bio, out);
|
||||||
|
if (out == NULL)
|
||||||
|
goto err;
|
||||||
|
+ pop_bio = asn_bio;
|
||||||
|
|
||||||
|
- BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
|
||||||
|
- BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
|
||||||
|
+ if (BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free) <= 0
|
||||||
|
+ || BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free) <= 0
|
||||||
|
+ || BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux) <= 0)
|
||||||
|
+ goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
- * Now let callback prepends any digest, cipher etc BIOs ASN1 structure
|
||||||
|
- * needs.
|
||||||
|
+ * Now let the callback prepend any digest, cipher, etc., that the BIO's
|
||||||
|
+ * ASN1 structure needs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sarg.out = out;
|
||||||
|
sarg.ndef_bio = NULL;
|
||||||
|
sarg.boundary = NULL;
|
||||||
|
|
||||||
|
- if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
|
||||||
|
+ /*
|
||||||
|
+ * The asn1_cb(), must not have mutated asn_bio on error, leaving it in the
|
||||||
|
+ * middle of some partially built, but not returned BIO chain.
|
||||||
|
+ */
|
||||||
|
+ if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) {
|
||||||
|
+ /*
|
||||||
|
+ * ndef_aux is now owned by asn_bio so we must not free it in the err
|
||||||
|
+ * clean up block
|
||||||
|
+ */
|
||||||
|
+ ndef_aux = NULL;
|
||||||
|
goto err;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We must not fail now because the callback has prepended additional
|
||||||
|
+ * BIOs to the chain
|
||||||
|
+ */
|
||||||
|
|
||||||
|
ndef_aux->val = val;
|
||||||
|
ndef_aux->it = it;
|
||||||
|
@@ -91,11 +116,11 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||||
|
ndef_aux->boundary = sarg.boundary;
|
||||||
|
ndef_aux->out = out;
|
||||||
|
|
||||||
|
- BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
|
||||||
|
-
|
||||||
|
return sarg.ndef_bio;
|
||||||
|
|
||||||
|
err:
|
||||||
|
+ /* BIO_pop() is NULL safe */
|
||||||
|
+ (void)BIO_pop(pop_bio);
|
||||||
|
BIO_free(asn_bio);
|
||||||
|
OPENSSL_free(ndef_aux);
|
||||||
|
return NULL;
|
||||||
|
diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
|
||||||
|
index 5dc6a3aebe..ec11bfc253 100644
|
||||||
|
--- a/test/recipes/80-test_cms.t
|
||||||
|
+++ b/test/recipes/80-test_cms.t
|
||||||
|
@@ -13,7 +13,7 @@ use warnings;
|
||||||
|
use POSIX;
|
||||||
|
use File::Spec::Functions qw/catfile/;
|
||||||
|
use File::Compare qw/compare_text/;
|
||||||
|
-use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file/;
|
||||||
|
+use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file with/;
|
||||||
|
use OpenSSL::Test::Utils;
|
||||||
|
|
||||||
|
setup("test_cms");
|
||||||
|
@@ -27,7 +27,7 @@ my $smcont = srctop_file("test", "smcont.txt");
|
||||||
|
my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib)
|
||||||
|
= disabled qw/des dh dsa ec ec2m rc2 zlib/;
|
||||||
|
|
||||||
|
-plan tests => 6;
|
||||||
|
+plan tests => 7;
|
||||||
|
|
||||||
|
my @smime_pkcs7_tests = (
|
||||||
|
|
||||||
|
@@ -584,3 +584,14 @@ sub check_availability {
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+# Check that we get the expected failure return code
|
||||||
|
+with({ exit_checker => sub { return shift == 6; } },
|
||||||
|
+ sub {
|
||||||
|
+ ok(run(app(['openssl', 'cms', '-encrypt',
|
||||||
|
+ '-in', srctop_file("test", "smcont.txt"),
|
||||||
|
+ '-stream', '-recip',
|
||||||
|
+ srctop_file("test/smime-certs", "badrsa.pem"),
|
||||||
|
+ ])),
|
||||||
|
+ "Check failure during BIO setup with -stream is handled correctly");
|
||||||
|
+ });
|
||||||
|
diff --git a/test/smime-certs/badrsa.pem b/test/smime-certs/badrsa.pem
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..f824fc2267
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/smime-certs/badrsa.pem
|
||||||
|
@@ -0,0 +1,18 @@
|
||||||
|
+-----BEGIN CERTIFICATE-----
|
||||||
|
+MIIDbTCCAlWgAwIBAgIToTV4Z0iuK08vZP20oTh//hC8BDANBgkqhkiG9w0BAQ0FADAtMSswKQYD
|
||||||
|
+VfcDEyJTYW1wbGUgTEFNUFMgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MCAXDTE5MTEyMDA2NTQxOFoY
|
||||||
|
+DzIwNTIwOTI3MDY1NDE4WjAZMRcwFQYDVQQDEw5BbGljZSBMb3ZlbGFjZTCCASIwDQYJKoZIhvcN
|
||||||
|
+AQEBBQADggEPADCCAQoCggEBALT0iehYOBY+TZp/T5K2KNI05Hwr+E3wP6XTvyi6WWyTgBK9LCOw
|
||||||
|
+I2juwdRrjFBmXkk7pWpjXwsA3A5GOtz0FpfgyC7OxsVcF7q4WHWZWleYXFKlQHJD73nQwXP968+A
|
||||||
|
+/3rBX7PhO0DBbZnfitOLPgPEwjTtdg0VQQ6Wz+CRQ/YbHPKaw7aRphZO63dKvIKp4cQVtkWQHi6s
|
||||||
|
+yTjGsgkLcLNau5LZDQUdsGV+SAo3nBdWCRYV+I65x8Kf4hCxqqmjV3d/2NKRu0BXnDe/N+iDz3X0
|
||||||
|
+zEoj0fqXgq4SWcC0nsG1lyyXt1TL270I6ATKRGJWiQVCCpDtc0NT6vdJ45bCSxgCAwEAAaOBlzCB
|
||||||
|
+lDAMBgNVHRMBAf8EAjAAMB4GA1UdEQQXMBWBE2FsaWNlQHNtaW1lLmV4YW1wbGUwEwYDVR0lBAww
|
||||||
|
+CgYIKwYBBQUHAwQwDwYDVR0PAQH/BAUDAwfAADAdBgNVHQ4EFgQUu/bMsi0dBhIcl64papAQ0yBm
|
||||||
|
+ZnMwHwYDVR0jBBgwFoAUeF8OWnjYa+RUcD2z3ez38fL6wEcwDQYJKoZIhvcNAQENBQADggEBABbW
|
||||||
|
+eonR6TMTckehDKNOabwaCIcekahAIL6l9tTzUX5ew6ufiAPlC6I/zQlmUaU0iSyFDG1NW14kNbFt
|
||||||
|
+5CAokyLhMtE4ASHBIHbiOp/ZSbUBTVYJZB61ot7w1/ol5QECSs08b8zrxIncf+t2DHGuVEy/Qq1d
|
||||||
|
+rBz8d4ay8zpqAE1tUyL5Da6ZiKUfWwZQXSI/JlbjQFzYQqTRDnzHWrg1xPeMTO1P2/cplFaseTiv
|
||||||
|
+yk4cYwOp/W9UAWymOZXF8WcJYCIUXkdcG/nEZxr057KlScrJmFXOoh7Y+8ON4iWYYcAfiNgpUFo/
|
||||||
|
+j8BAwrKKaFvdlZS9k1Ypb2+UQY75mKJE9Bg=
|
||||||
|
+-----END CERTIFICATE-----
|
|
@ -0,0 +1,44 @@
|
||||||
|
diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509v3/v3_genn.c
|
||||||
|
index 87a5eff47c..e54ddc55c9 100644
|
||||||
|
--- a/crypto/x509v3/v3_genn.c
|
||||||
|
+++ b/crypto/x509v3/v3_genn.c
|
||||||
|
@@ -98,7 +98,7 @@ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
|
||||||
|
return -1;
|
||||||
|
switch (a->type) {
|
||||||
|
case GEN_X400:
|
||||||
|
- result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
|
||||||
|
+ result = ASN1_STRING_cmp(a->d.x400Address, b->d.x400Address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GEN_EDIPARTY:
|
||||||
|
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h
|
||||||
|
index 90fa3592ce..e61c0f29d4 100644
|
||||||
|
--- a/include/openssl/x509v3.h
|
||||||
|
+++ b/include/openssl/x509v3.h
|
||||||
|
@@ -136,7 +136,7 @@ typedef struct GENERAL_NAME_st {
|
||||||
|
OTHERNAME *otherName; /* otherName */
|
||||||
|
ASN1_IA5STRING *rfc822Name;
|
||||||
|
ASN1_IA5STRING *dNSName;
|
||||||
|
- ASN1_TYPE *x400Address;
|
||||||
|
+ ASN1_STRING *x400Address;
|
||||||
|
X509_NAME *directoryName;
|
||||||
|
EDIPARTYNAME *ediPartyName;
|
||||||
|
ASN1_IA5STRING *uniformResourceIdentifier;
|
||||||
|
diff --git a/test/v3nametest.c b/test/v3nametest.c
|
||||||
|
index d1852190b8..37819da8fd 100644
|
||||||
|
--- a/test/v3nametest.c
|
||||||
|
+++ b/test/v3nametest.c
|
||||||
|
@@ -646,6 +646,14 @@ static struct gennamedata {
|
||||||
|
0xb7, 0x09, 0x02, 0x02
|
||||||
|
},
|
||||||
|
15
|
||||||
|
+ }, {
|
||||||
|
+ /*
|
||||||
|
+ * Regression test for CVE-2023-0286.
|
||||||
|
+ */
|
||||||
|
+ {
|
||||||
|
+ 0xa3, 0x00
|
||||||
|
+ },
|
||||||
|
+ 2
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in New Issue