diff --git a/dist b/dist new file mode 100644 index 0000000000000000000000000000000000000000..535c6900412d365bb0ff6de8d1f27110833b3ae3 --- /dev/null +++ b/dist @@ -0,0 +1 @@ +an8_7 diff --git a/openssl-1.1.1-cleanup-peer-point-reneg.patch b/openssl-1.1.1-cleanup-peer-point-reneg.patch index 8ea99e0a9cf3e465d5ac9a801d4e3f8e8327afd7..a98d34e9ed66148029e44bf1e73f9b9e03ab7f3f 100644 --- a/openssl-1.1.1-cleanup-peer-point-reneg.patch +++ b/openssl-1.1.1-cleanup-peer-point-reneg.patch @@ -1,11 +1,13 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl/statem/extensions.c --- openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg 2021-03-25 14:28:38.000000000 +0100 +++ openssl-1.1.1k/ssl/statem/extensions.c 2021-06-24 16:16:19.526181743 +0200 -@@ -42,6 +42,7 @@ static int tls_parse_certificate_authori +@@ -42,6 +42,9 @@ static int tls_parse_certificate_authori #ifndef OPENSSL_NO_SRP static int init_srp(SSL *s, unsigned int context); #endif ++#ifndef OPENSSL_NO_EC +static int init_ec_point_formats(SSL *s, unsigned int context); ++#endif static int init_etm(SSL *s, unsigned int context); static int init_ems(SSL *s, unsigned int context); static int final_ems(SSL *s, unsigned int context, int sent); @@ -18,10 +20,11 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl tls_construct_stoc_ec_pt_formats, tls_construct_ctos_ec_pt_formats, final_ec_pt_formats }, -@@ -1164,6 +1165,15 @@ static int init_srp(SSL *s, unsigned int +@@ -1164,6 +1165,17 @@ static int init_srp(SSL *s, unsigned int } #endif ++#ifndef OPENSSL_NO_EC +static int init_ec_point_formats(SSL *s, unsigned int context) +{ + OPENSSL_free(s->ext.peer_ecpointformats); @@ -30,6 +33,7 @@ diff -up openssl-1.1.1k/ssl/statem/extensions.c.cleanup-reneg openssl-1.1.1k/ssl + + return 1; +} ++#endif + static int init_etm(SSL *s, unsigned int context) { 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 0000000000000000000000000000000000000000..9a888a6dee11371218f1a2d127272b796d13263f --- /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-1.1.1-cve-2022-4450-PEM-bio.patch b/openssl-1.1.1-cve-2022-4450-PEM-bio.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2e9f228bd2dd09c7a19a99a8e04edeb88e59883 --- /dev/null +++ b/openssl-1.1.1-cve-2022-4450-PEM-bio.patch @@ -0,0 +1,103 @@ +From bbcf509bd046b34cca19c766bbddc31683d0858b Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 13 Dec 2022 14:54:55 +0000 +Subject: [PATCH 2/6] Avoid dangling ptrs in header and data params for + PEM_read_bio_ex + +In the event of a failure in PEM_read_bio_ex() we free the buffers we +allocated for the header and data buffers. However we were not clearing +the ptrs stored in *header and *data. Since, on success, the caller is +responsible for freeing these ptrs this can potentially lead to a double +free if the caller frees them even on failure. + +Thanks to Dawei Wang for reporting this issue. + +Based on a proposed patch by Kurt Roeckx. + +CVE-2022-4450 + +Reviewed-by: Paul Dale +Reviewed-by: Hugo Landau +--- + crypto/pem/pem_lib.c | 2 ++ + 1 file changed, 2 insertions(+) + +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); +-- +2.39.1 + +From 2bd611267868a008afa576846ba71566bd0d4d15 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Tue, 13 Dec 2022 15:02:26 +0000 +Subject: [PATCH 3/6] Add a test for CVE-2022-4450 + +Call PEM_read_bio_ex() and expect a failure. There should be no dangling +ptrs and therefore there should be no double free if we free the ptrs on +error. + +Reviewed-by: Paul Dale +Reviewed-by: Hugo Landau +--- + test/pemtest.c | 30 ++++++++++++++++++++++++++++++ + 1 file changed, 30 insertions(+) + +diff --git a/test/pemtest.c b/test/pemtest.c +index 3203d976be..edeb0a1205 100644 +--- a/test/pemtest.c ++++ b/test/pemtest.c +@@ -83,9 +83,39 @@ static int test_invalid(void) + return 1; + } + ++static int test_empty_payload(void) ++{ ++ BIO *b; ++ static char *emptypay = ++ "-----BEGIN CERTIFICATE-----\n" ++ "-\n" /* Base64 EOF character */ ++ "-----END CERTIFICATE-----"; ++ char *name = NULL, *header = NULL; ++ unsigned char *data = NULL; ++ long len; ++ int ret = 0; ++ ++ b = BIO_new_mem_buf(emptypay, strlen(emptypay)); ++ if (!TEST_ptr(b)) ++ return 0; ++ ++ /* Expected to fail because the payload is empty */ ++ if (!TEST_false(PEM_read_bio_ex(b, &name, &header, &data, &len, 0))) ++ goto err; ++ ++ ret = 1; ++ err: ++ OPENSSL_free(name); ++ OPENSSL_free(header); ++ OPENSSL_free(data); ++ BIO_free(b); ++ return ret; ++} ++ + int setup_tests(void) + { + ADD_ALL_TESTS(test_b64, OSSL_NELEM(b64_pem_data)); + ADD_TEST(test_invalid); ++ ADD_TEST(test_empty_payload); + return 1; + } +-- +2.39.1 + diff --git a/openssl-1.1.1-cve-2023-0215-BIO-UAF.patch b/openssl-1.1.1-cve-2023-0215-BIO-UAF.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b8fdb53c2193f592da31b890fc3a5cc5b3873ee --- /dev/null +++ b/openssl-1.1.1-cve-2023-0215-BIO-UAF.patch @@ -0,0 +1,186 @@ +From c3829dd8825c654652201e16f8a0a0c46ee3f344 Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 14 Dec 2022 16:18:14 +0000 +Subject: [PATCH 4/6] Fix a UAF resulting from a bug in BIO_new_NDEF + +If the aux->asn1_cb() call fails in BIO_new_NDEF then the "out" BIO will +be part of an invalid BIO chain. This causes a "use after free" when the +BIO is eventually freed. + +Based on an original patch by Viktor Dukhovni and an idea from Theo +Buehler. + +Thanks to Octavio Galland for reporting this issue. + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +--- + crypto/asn1/bio_ndef.c | 39 ++++++++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 7 deletions(-) + +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; +-- +2.39.1 + +From f040f2577891d2bdb7610566c172233844cf673a Mon Sep 17 00:00:00 2001 +From: Matt Caswell +Date: Wed, 14 Dec 2022 17:15:18 +0000 +Subject: [PATCH 5/6] Check CMS failure during BIO setup with -stream is + handled correctly + +Test for the issue fixed in the previous commit + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +--- + test/recipes/80-test_cms.t | 15 +++++++++++++-- + test/smime-certs/badrsa.pem | 18 ++++++++++++++++++ + 2 files changed, 31 insertions(+), 2 deletions(-) + create mode 100644 test/smime-certs/badrsa.pem + +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----- +-- +2.39.1 + diff --git a/openssl-1.1.1-cve-2023-0286-X400.patch b/openssl-1.1.1-cve-2023-0286-X400.patch new file mode 100644 index 0000000000000000000000000000000000000000..170699e53bd7c312e62c1761fe6a78fd560e13ba --- /dev/null +++ b/openssl-1.1.1-cve-2023-0286-X400.patch @@ -0,0 +1,63 @@ +From 2c6c9d439b484e1ba9830d8454a34fa4f80fdfe9 Mon Sep 17 00:00:00 2001 +From: Hugo Landau +Date: Tue, 17 Jan 2023 17:45:42 +0000 +Subject: [PATCH 6/6] CVE-2023-0286: Fix GENERAL_NAME_cmp for x400Address + (1.1.1) + +Reviewed-by: Paul Dale +Reviewed-by: Tomas Mraz +--- + CHANGES | 18 +++++++++++++++++- + crypto/x509v3/v3_genn.c | 2 +- + include/openssl/x509v3.h | 2 +- + test/v3nametest.c | 8 ++++++++ + 4 files changed, 27 insertions(+), 3 deletions(-) + +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 + } + }; + +-- +2.39.1 + diff --git a/openssl-1.1.1-sm2-sign-verify.patch b/openssl-1.1.1-sm2-sign-verify.patch deleted file mode 100644 index de140e42ce66820705235ef8d3830dd66f826664..0000000000000000000000000000000000000000 --- a/openssl-1.1.1-sm2-sign-verify.patch +++ /dev/null @@ -1,1193 +0,0 @@ -From fb550a3f0eb25e127e9f60343af28be4f8e72c1a Mon Sep 17 00:00:00 2001 -From: Tianjia Zhang -Date: Tue, 29 Nov 2022 11:16:23 +0800 -Subject: [PATCH] SM2: Add distid parameter for signature sign and verify - -According to the specifications GM/T 0003.2-2012 and GM/T 0003.5-2012, -the SM2 algorithm signature requires a Za value when generating the hash -required for signature. The Za value is generated by the fixed parameter -of the elliptic curve, the public key and the user entered identifiable ID. -This patch adds a distid parameter to specify the ID during signature sign -and verification. - -An example usage for generating a self signed CA certificate is as follows: - - openssl ecparam -genkey -name SM2 -text -out ca.key - openssl req -verbose -new -days 10000 -x509 \ - -sm3 -sigopt "distid:1234567812345678" \ - -config genkey.conf \ - -key ca.key \ - -out ca.crt - -The genkey.conf file content is as follows: - - [ req ] - distinguished_name = req_distinguished_name - prompt = no - string_mask = utf8only - x509_extensions = v3_ca - - [ req_distinguished_name ] - O = rfc8998-CA - CN = RFC8998 certificate signing key - emailAddress = ca@rfc8998-ca - - [ v3_ca ] - basicConstraints=CA:TRUE - subjectKeyIdentifier=hash - authorityKeyIdentifier=keyid:always,issuer - - [ skid ] - basicConstraints=CA:TRUE - subjectKeyIdentifier=12345678 - authorityKeyIdentifier=keyid:always,issuer - -Signed-off-by: Tianjia Zhang ---- - apps/apps.c | 20 +++++++ - apps/apps.h | 3 + - apps/ca.c | 28 ++++++--- - apps/crl.c | 1 + - apps/req.c | 116 ++++++++++++++++++++++++++++++++++-- - apps/verify.c | 1 + - apps/x509.c | 16 ++++- - crypto/asn1/a_sign.c | 10 +++- - crypto/asn1/a_verify.c | 46 ++++++++------ - crypto/asn1/asn1_err.c | 2 + - crypto/asn1/d2i_pu.c | 3 + - crypto/asn1/i2d_pu.c | 3 + - crypto/ec/ec_ameth.c | 2 +- - crypto/ec/ec_curve.c | 43 +++++++++++++ - crypto/err/openssl.txt | 1 + - crypto/evp/evp_pkey.c | 11 ++++ - crypto/objects/obj_dat.h | 15 +++-- - crypto/objects/obj_mac.num | 1 + - crypto/objects/obj_xref.h | 2 + - crypto/objects/obj_xref.txt | 2 + - crypto/objects/objects.txt | 1 + - crypto/sm2/sm2_pmeth.c | 43 +++++++++++-- - crypto/x509/x_all.c | 15 +++++ - crypto/x509/x_pubkey.c | 11 ++++ - fuzz/oids.txt | 1 + - include/crypto/sm2.h | 1 + - include/openssl/asn1err.h | 1 + - include/openssl/obj_mac.h | 5 ++ - include/openssl/x509.h | 5 ++ - util/libcrypto.num | 3 + - 30 files changed, 367 insertions(+), 45 deletions(-) - -diff --git a/apps/apps.c b/apps/apps.c -index c06241abb975..f8eb5c99bd0f 100644 ---- a/apps/apps.c -+++ b/apps/apps.c -@@ -781,6 +781,16 @@ EVP_PKEY *load_key(const char *file, int format, int maybe_stdin, - BIO_printf(bio_err, "unable to load %s\n", key_descrip); - ERR_print_errors(bio_err); - } -+#ifndef OPENSSL_NO_SM2 -+ else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { -+ EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); -+ if (eckey) { -+ const EC_GROUP *group = EC_KEY_get0_group(eckey); -+ if (group && EC_GROUP_get_curve_name(group) == NID_sm2) -+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); -+ } -+ } -+#endif - return pkey; - } - -@@ -867,6 +877,16 @@ EVP_PKEY *load_pubkey(const char *file, int format, int maybe_stdin, - BIO_free(key); - if (pkey == NULL) - BIO_printf(bio_err, "unable to load %s\n", key_descrip); -+#ifndef OPENSSL_NO_SM2 -+ else if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { -+ EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); -+ if (eckey) { -+ const EC_GROUP *group = EC_KEY_get0_group(eckey); -+ if (group && EC_GROUP_get_curve_name(group) == NID_sm2) -+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); -+ } -+ } -+#endif - return pkey; - } - -diff --git a/apps/apps.h b/apps/apps.h -index 34c3fd8633c1..8456dff31ceb 100644 ---- a/apps/apps.h -+++ b/apps/apps.h -@@ -557,6 +557,9 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts); - int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, - STACK_OF(OPENSSL_STRING) *sigopts); -+int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts); -+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, -+ STACK_OF(OPENSSL_STRING) *vfyopts); - - extern char *psk_key; - -diff --git a/apps/ca.c b/apps/ca.c -index 89491b6e6cb0..ae85b538d651 100755 ---- a/apps/ca.c -+++ b/apps/ca.c -@@ -90,6 +90,7 @@ static char *lookup_conf(const CONF *conf, const char *group, const char *tag); - - static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(OPENSSL_STRING) *vfyopts, - STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, const char *subj, unsigned long chtype, - int multirdn, int email_dn, const char *startdate, -@@ -99,6 +100,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - int default_op, int ext_copy, int selfsign); - static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(OPENSSL_STRING) *vfyopts, - STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, const char *subj, unsigned long chtype, - int multirdn, int email_dn, const char *startdate, -@@ -142,7 +144,7 @@ typedef enum OPTION_choice { - OPT_CREATE_SERIAL, OPT_MULTIVALUE_RDN, OPT_STARTDATE, OPT_ENDDATE, - OPT_DAYS, OPT_MD, OPT_POLICY, OPT_KEYFILE, OPT_KEYFORM, OPT_PASSIN, - OPT_KEY, OPT_CERT, OPT_SELFSIGN, OPT_IN, OPT_OUT, OPT_OUTDIR, -- OPT_SIGOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, -+ OPT_SIGOPT, OPT_VFYOPT, OPT_NOTEXT, OPT_BATCH, OPT_PRESERVEDN, OPT_NOEMAILDN, - OPT_GENCRL, OPT_MSIE_HACK, OPT_CRLDAYS, OPT_CRLHOURS, OPT_CRLSEC, - OPT_INFILES, OPT_SS_CERT, OPT_SPKAC, OPT_REVOKE, OPT_VALID, - OPT_EXTENSIONS, OPT_EXTFILE, OPT_STATUS, OPT_UPDATEDB, OPT_CRLEXTS, -@@ -182,6 +184,7 @@ const OPTIONS ca_options[] = { - {"out", OPT_OUT, '>', "Where to put the output file(s)"}, - {"outdir", OPT_OUTDIR, '/', "Where to put output cert"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, - {"notext", OPT_NOTEXT, '-', "Do not print the generated certificate"}, - {"batch", OPT_BATCH, '-', "Don't ask questions"}, - {"preserveDN", OPT_PRESERVEDN, '-', "Don't re-order the DN"}, -@@ -233,7 +236,7 @@ int ca_main(int argc, char **argv) - CA_DB *db = NULL; - DB_ATTR db_attr; - STACK_OF(CONF_VALUE) *attribs = NULL; -- STACK_OF(OPENSSL_STRING) *sigopts = NULL; -+ STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL; - STACK_OF(X509) *cert_sk = NULL; - X509_CRL *crl = NULL; - const EVP_MD *dgst = NULL; -@@ -354,6 +357,12 @@ opthelp: - if (sigopts == NULL || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) - goto end; - break; -+ case OPT_VFYOPT: -+ if (vfyopts == NULL) -+ vfyopts = sk_OPENSSL_STRING_new_null(); -+ if (vfyopts == NULL || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) -+ goto end; -+ break; - case OPT_NOTEXT: - notext = 1; - break; -@@ -890,7 +899,7 @@ end_of_options: - if (ss_cert_file != NULL) { - total++; - j = certify_cert(&x, ss_cert_file, pkey, x509, dgst, sigopts, -- attribs, -+ vfyopts, attribs, - db, serial, subj, chtype, multirdn, email_dn, - startdate, enddate, days, batch, extensions, - conf, verbose, certopt, get_nameopt(), default_op, -@@ -910,7 +919,8 @@ end_of_options: - } - if (infile != NULL) { - total++; -- j = certify(&x, infile, pkey, x509p, dgst, sigopts, attribs, db, -+ j = certify(&x, infile, pkey, x509p, dgst, sigopts, -+ vfyopts, attribs, db, - serial, subj, chtype, multirdn, email_dn, startdate, - enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); -@@ -929,7 +939,8 @@ end_of_options: - } - for (i = 0; i < argc; i++) { - total++; -- j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, attribs, db, -+ j = certify(&x, argv[i], pkey, x509p, dgst, sigopts, -+ vfyopts, attribs, db, - serial, subj, chtype, multirdn, email_dn, startdate, - enddate, days, batch, extensions, conf, verbose, - certopt, get_nameopt(), default_op, ext_copy, selfsign); -@@ -1243,6 +1254,7 @@ end_of_options: - BN_free(crlnumber); - free_index(db); - sk_OPENSSL_STRING_free(sigopts); -+ sk_OPENSSL_STRING_free(vfyopts); - EVP_PKEY_free(pkey); - X509_free(x509); - X509_CRL_free(crl); -@@ -1262,6 +1274,7 @@ static char *lookup_conf(const CONF *conf, const char *section, const char *tag) - - static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(OPENSSL_STRING) *vfyopts, - STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, const char *subj, unsigned long chtype, - int multirdn, int email_dn, const char *startdate, -@@ -1300,7 +1313,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - BIO_printf(bio_err, "error unpacking public key\n"); - goto end; - } -- i = X509_REQ_verify(req, pktmp); -+ i = do_X509_REQ_verify(req, pktmp, vfyopts); - pktmp = NULL; - if (i < 0) { - ok = 0; -@@ -1331,6 +1344,7 @@ static int certify(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - - static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x509, - const EVP_MD *dgst, STACK_OF(OPENSSL_STRING) *sigopts, -+ STACK_OF(OPENSSL_STRING) *vfyopts, - STACK_OF(CONF_VALUE) *policy, CA_DB *db, - BIGNUM *serial, const char *subj, unsigned long chtype, - int multirdn, int email_dn, const char *startdate, -@@ -1354,7 +1368,7 @@ static int certify_cert(X509 **xret, const char *infile, EVP_PKEY *pkey, X509 *x - BIO_printf(bio_err, "error unpacking public key\n"); - goto end; - } -- i = X509_verify(req, pktmp); -+ i = do_X509_verify(req, pktmp, vfyopts); - if (i < 0) { - ok = 0; - BIO_printf(bio_err, "Signature verification problems....\n"); -diff --git a/apps/crl.c b/apps/crl.c -index 031fada14c84..0dad64d55d0a 100644 ---- a/apps/crl.c -+++ b/apps/crl.c -@@ -208,6 +208,7 @@ int crl_main(int argc, char **argv) - BIO_printf(bio_err, "Error getting CRL issuer public key\n"); - goto end; - } -+ /* SM2: TODO */ - i = X509_CRL_verify(x, pkey); - EVP_PKEY_free(pkey); - if (i < 0) -diff --git a/apps/req.c b/apps/req.c -index a603907cd5af..796427f0a596 100644 ---- a/apps/req.c -+++ b/apps/req.c -@@ -86,7 +86,7 @@ typedef enum OPTION_choice { - OPT_INFORM, OPT_OUTFORM, OPT_ENGINE, OPT_KEYGEN_ENGINE, OPT_KEY, - OPT_PUBKEY, OPT_NEW, OPT_CONFIG, OPT_KEYFORM, OPT_IN, OPT_OUT, - OPT_KEYOUT, OPT_PASSIN, OPT_PASSOUT, OPT_NEWKEY, -- OPT_PKEYOPT, OPT_SIGOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, -+ OPT_PKEYOPT, OPT_SIGOPT, OPT_VFYOPT, OPT_BATCH, OPT_NEWHDR, OPT_MODULUS, - OPT_VERIFY, OPT_NODES, OPT_NOOUT, OPT_VERBOSE, OPT_UTF8, - OPT_NAMEOPT, OPT_REQOPT, OPT_SUBJ, OPT_SUBJECT, OPT_TEXT, OPT_X509, - OPT_MULTIVALUE_RDN, OPT_DAYS, OPT_SET_SERIAL, OPT_ADDEXT, OPT_EXTENSIONS, -@@ -112,6 +112,7 @@ const OPTIONS req_options[] = { - {"newkey", OPT_NEWKEY, 's', "Specify as type:bits"}, - {"pkeyopt", OPT_PKEYOPT, 's', "Public key options as opt:value"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, - {"batch", OPT_BATCH, '-', - "Do not ask anything during request generation"}, - {"newhdr", OPT_NEWHDR, '-', "Output \"NEW\" in the header lines"}, -@@ -219,7 +220,7 @@ int req_main(int argc, char **argv) - ENGINE *e = NULL, *gen_eng = NULL; - EVP_PKEY *pkey = NULL; - EVP_PKEY_CTX *genctx = NULL; -- STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL; -+ STACK_OF(OPENSSL_STRING) *pkeyopts = NULL, *sigopts = NULL, *vfyopts = NULL; - LHASH_OF(OPENSSL_STRING) *addexts = NULL; - X509 *x509ss = NULL; - X509_REQ *req = NULL; -@@ -330,6 +331,12 @@ int req_main(int argc, char **argv) - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) - goto opthelp; - break; -+ case OPT_VFYOPT: -+ if (!vfyopts) -+ vfyopts = sk_OPENSSL_STRING_new_null(); -+ if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) -+ goto opthelp; -+ break; - case OPT_BATCH: - batch = 1; - break; -@@ -849,7 +856,7 @@ int req_main(int argc, char **argv) - goto end; - } - -- i = X509_REQ_verify(req, tpubkey); -+ i = do_X509_REQ_verify(req, tpubkey, vfyopts); - - if (i < 0) { - goto end; -@@ -969,6 +976,7 @@ int req_main(int argc, char **argv) - EVP_PKEY_CTX_free(genctx); - sk_OPENSSL_STRING_free(pkeyopts); - sk_OPENSSL_STRING_free(sigopts); -+ sk_OPENSSL_STRING_free(vfyopts); - lh_OPENSSL_STRING_doall(addexts, exts_cleanup); - lh_OPENSSL_STRING_free(addexts); - #ifndef OPENSSL_NO_ENGINE -@@ -1614,11 +1622,36 @@ static int genpkey_cb(EVP_PKEY_CTX *ctx) - static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, - const EVP_MD *md, STACK_OF(OPENSSL_STRING) *sigopts) - { -- EVP_PKEY_CTX *pkctx = NULL; -+ EVP_PKEY_CTX *pkctx; - int i, def_nid; - - if (ctx == NULL) - return 0; -+ -+ pkctx = EVP_PKEY_CTX_new(pkey, NULL); -+ if (pkctx == NULL) -+ return 0; -+ -+ EVP_MD_CTX_set_pkey_ctx(ctx, pkctx); -+ -+#ifndef OPENSSL_NO_SM2 -+ if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) { -+ for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { -+ char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); -+ if (strncmp(sigopt, "distid:", 7) == 0) { -+ if (pkey_ctrl_string(pkctx, sigopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ sk_OPENSSL_STRING_delete(sigopts, i); -+ break; -+ } -+ } -+ } -+#endif -+ - /* - * EVP_PKEY_get_default_digest_nid() returns 2 if the digest is mandatory - * for this algorithm. -@@ -1628,7 +1661,7 @@ static int do_sign_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, - /* The signing algorithm requires there to be no digest */ - md = NULL; - } -- if (!EVP_DigestSignInit(ctx, &pkctx, md, NULL, pkey)) -+ if (!EVP_DigestSignInit(ctx, NULL, md, NULL, pkey)) - return 0; - for (i = 0; i < sk_OPENSSL_STRING_num(sigopts); i++) { - char *sigopt = sk_OPENSSL_STRING_value(sigopts, i); -@@ -1650,6 +1683,7 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md, - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_sign_ctx(x, mctx); -+ EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(mctx)); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; - } -@@ -1662,6 +1696,7 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md, - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_REQ_sign_ctx(x, mctx); -+ EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(mctx)); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; - } -@@ -1674,6 +1709,77 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md, - rv = do_sign_init(mctx, pkey, md, sigopts); - if (rv > 0) - rv = X509_CRL_sign_ctx(x, mctx); -+ EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(mctx)); -+ EVP_MD_CTX_free(mctx); -+ return rv > 0 ? 1 : 0; -+} -+ -+static int do_verify_init(EVP_MD_CTX *ctx, EVP_PKEY *pkey, -+ STACK_OF(OPENSSL_STRING) *vfyopts) -+{ -+ EVP_PKEY_CTX *pkctx; -+ int i; -+ -+ if (ctx == NULL) -+ return 0; -+ -+ pkctx = EVP_PKEY_CTX_new(pkey, NULL); -+ if (pkctx == NULL) -+ return 0; -+ -+ EVP_MD_CTX_set_pkey_ctx(ctx, pkctx); -+ -+#ifndef OPENSSL_NO_SM2 -+ if (EVP_PKEY_id(pkey) == EVP_PKEY_SM2) { -+ for (i = 0; i < sk_OPENSSL_STRING_num(vfyopts); i++) { -+ char *sigopt = sk_OPENSSL_STRING_value(vfyopts, i); -+ if (strncmp(sigopt, "distid:", 7) == 0) { -+ if (pkey_ctrl_string(pkctx, sigopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ -+ sk_OPENSSL_STRING_delete(vfyopts, i); -+ break; -+ } -+ } -+ } -+#endif -+ -+ for (i = 0; i < sk_OPENSSL_STRING_num(vfyopts); i++) { -+ char *sigopt = sk_OPENSSL_STRING_value(vfyopts, i); -+ if (pkey_ctrl_string(pkctx, sigopt) <= 0) { -+ BIO_printf(bio_err, "parameter error \"%s\"\n", sigopt); -+ ERR_print_errors(bio_err); -+ return 0; -+ } -+ } -+ -+ return 1; -+} -+ -+int do_X509_verify(X509 *x, EVP_PKEY *pkey, STACK_OF(OPENSSL_STRING) *vfyopts) -+{ -+ int rv; -+ EVP_MD_CTX *mctx = EVP_MD_CTX_new(); -+ rv = do_verify_init(mctx, pkey, vfyopts); -+ if (rv > 0) -+ rv = X509_verify_ctx(x, pkey, mctx); -+ EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(mctx)); -+ EVP_MD_CTX_free(mctx); -+ return rv > 0 ? 1 : 0; -+} -+ -+int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, -+ STACK_OF(OPENSSL_STRING) *vfyopts) -+{ -+ int rv; -+ EVP_MD_CTX *mctx = EVP_MD_CTX_new(); -+ rv = do_verify_init(mctx, pkey, vfyopts); -+ if (rv > 0) -+ rv = X509_REQ_verify_ctx(x, pkey, mctx); -+ EVP_PKEY_CTX_free(EVP_MD_CTX_pkey_ctx(mctx)); - EVP_MD_CTX_free(mctx); - return rv > 0 ? 1 : 0; - } -diff --git a/apps/verify.c b/apps/verify.c -index 1f9385606046..770016b5ca0d 100644 ---- a/apps/verify.c -+++ b/apps/verify.c -@@ -234,6 +234,7 @@ static int check(X509_STORE *ctx, const char *file, - X509_STORE_CTX_set0_trusted_stack(csc, tchain); - if (crls != NULL) - X509_STORE_CTX_set0_crls(csc, crls); -+ /* SM2: TODO */ - i = X509_verify_cert(csc); - if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) { - printf("%s: OK\n", (file == NULL) ? "stdin" : file); -diff --git a/apps/x509.c b/apps/x509.c -index 1043eba0c8a0..ebb2eca98499 100644 ---- a/apps/x509.c -+++ b/apps/x509.c -@@ -48,7 +48,7 @@ static int print_x509v3_exts(BIO *bio, X509 *x, const char *exts); - typedef enum OPTION_choice { - OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, - OPT_INFORM, OPT_OUTFORM, OPT_KEYFORM, OPT_REQ, OPT_CAFORM, -- OPT_CAKEYFORM, OPT_SIGOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, -+ OPT_CAKEYFORM, OPT_SIGOPT, OPT_VFYOPT, OPT_DAYS, OPT_PASSIN, OPT_EXTFILE, - OPT_EXTENSIONS, OPT_IN, OPT_OUT, OPT_SIGNKEY, OPT_CA, - OPT_CAKEY, OPT_CASERIAL, OPT_SET_SERIAL, OPT_FORCE_PUBKEY, - OPT_ADDTRUST, OPT_ADDREJECT, OPT_SETALIAS, OPT_CERTOPT, OPT_NAMEOPT, -@@ -132,6 +132,7 @@ const OPTIONS x509_options[] = { - {"CAform", OPT_CAFORM, 'F', "CA format - default PEM"}, - {"CAkeyform", OPT_CAKEYFORM, 'E', "CA key format - default PEM"}, - {"sigopt", OPT_SIGOPT, 's', "Signature parameter in n:v form"}, -+ {"vfyopt", OPT_VFYOPT, 's', "CSR verification parameter in n:v form"}, - {"force_pubkey", OPT_FORCE_PUBKEY, '<', "Force the Key to put inside certificate"}, - {"next_serial", OPT_NEXT_SERIAL, '-', "Increment current certificate serial number"}, - {"clrreject", OPT_CLRREJECT, '-', -@@ -159,7 +160,7 @@ int x509_main(int argc, char **argv) - CONF *extconf = NULL; - EVP_PKEY *Upkey = NULL, *CApkey = NULL, *fkey = NULL; - STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL; -- STACK_OF(OPENSSL_STRING) *sigopts = NULL; -+ STACK_OF(OPENSSL_STRING) *sigopts = NULL, *vfyopts = NULL; - X509 *x = NULL, *xca = NULL; - X509_REQ *req = NULL, *rq = NULL; - X509_STORE *ctx = NULL; -@@ -241,6 +242,12 @@ int x509_main(int argc, char **argv) - if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, opt_arg())) - goto opthelp; - break; -+ case OPT_VFYOPT: -+ if (!vfyopts) -+ vfyopts = sk_OPENSSL_STRING_new_null(); -+ if (!vfyopts || !sk_OPENSSL_STRING_push(vfyopts, opt_arg())) -+ goto opthelp; -+ break; - case OPT_DAYS: - if (preserve_dates) - goto opthelp; -@@ -535,7 +542,7 @@ int x509_main(int argc, char **argv) - BIO_printf(bio_err, "error unpacking public key\n"); - goto end; - } -- i = X509_REQ_verify(req, pkey); -+ i = do_X509_REQ_verify(req, pkey, vfyopts); - if (i < 0) { - BIO_printf(bio_err, "Signature verification error\n"); - ERR_print_errors(bio_err); -@@ -544,6 +551,7 @@ int x509_main(int argc, char **argv) - if (i == 0) { - BIO_printf(bio_err, - "Signature did not match the certificate request\n"); -+ ERR_print_errors(bio_err); - goto end; - } else { - BIO_printf(bio_err, "Signature ok\n"); -@@ -799,6 +807,7 @@ int x509_main(int argc, char **argv) - goto end; - } - -+ /* SM2: TODO */ - if (!sign(x, Upkey, days, clrext, digest, extconf, extsect, preserve_dates)) - goto end; - } else if (CA_flag == i) { -@@ -898,6 +907,7 @@ int x509_main(int argc, char **argv) - EVP_PKEY_free(CApkey); - EVP_PKEY_free(fkey); - sk_OPENSSL_STRING_free(sigopts); -+ sk_OPENSSL_STRING_free(vfyopts); - X509_REQ_free(rq); - ASN1_INTEGER_free(sno); - sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free); -diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c -index 72381b665551..5ca7d733801a 100644 ---- a/crypto/asn1/a_sign.c -+++ b/crypto/asn1/a_sign.c -@@ -145,6 +145,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, - unsigned char *buf_in = NULL, *buf_out = NULL; - size_t inl = 0, outl = 0, outll = 0; - int signid, paramtype, buf_len = 0; -+ int pkey_id; - int rv; - - type = EVP_MD_CTX_md(ctx); -@@ -184,9 +185,16 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); - goto err; - } -+ -+ pkey_id = pkey->ameth->pkey_id; -+#ifndef OPENSSL_NO_SM2 -+ if (pkey_id == EVP_PKEY_EC && EVP_PKEY_id(pkey) == EVP_PKEY_SM2) -+ pkey_id = EVP_PKEY_SM2; -+#endif -+ - if (!OBJ_find_sigid_by_algs(&signid, - EVP_MD_nid(type), -- pkey->ameth->pkey_id)) { -+ pkey_id)) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, - ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); - goto err; -diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c -index 5e7a1d9ac381..1c0ee1f96040 100644 ---- a/crypto/asn1/a_verify.c -+++ b/crypto/asn1/a_verify.c -@@ -91,36 +91,47 @@ int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, - int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) - { -- EVP_MD_CTX *ctx = NULL; -+ EVP_MD_CTX *ctx = EVP_MD_CTX_new(); -+ int ret; -+ -+ if (ctx == NULL) { -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ -+ ret = ASN1_item_verify_ctx(it, a, signature, asn, pkey, ctx); -+ -+ EVP_MD_CTX_free(ctx); -+ return ret; -+} -+ -+int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, -+ ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, -+ EVP_MD_CTX *ctx) -+{ - unsigned char *buf_in = NULL; - int ret = -1, inl = 0; - int mdnid, pknid; - size_t inll = 0; - - if (!pkey) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - - if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - return -1; - } - -- ctx = EVP_MD_CTX_new(); -- if (ctx == NULL) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); -- goto err; -- } -- - /* Convert signature OID into digest and public key OIDs */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } - if (mdnid == NID_undef) { - if (!pkey->ameth || !pkey->ameth->item_verify) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, - ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } -@@ -143,19 +154,19 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - const EVP_MD *type = EVP_get_digestbynid(mdnid); - - if (type == NULL) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, - ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); - goto err; - } - - /* Check public key OID matches public key type */ - if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ASN1_R_WRONG_PUBLIC_KEY_TYPE); - goto err; - } - - if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ERR_R_EVP_LIB); - ret = 0; - goto err; - } -@@ -164,11 +175,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - - inl = ASN1_item_i2d(asn, &buf_in, it); - if (inl <= 0) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_INTERNAL_ERROR); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ERR_R_INTERNAL_ERROR); - goto err; - } - if (buf_in == NULL) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ERR_R_MALLOC_FAILURE); - goto err; - } - inll = inl; -@@ -176,12 +187,11 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ret = EVP_DigestVerify(ctx, signature->data, (size_t)signature->length, - buf_in, inl); - if (ret <= 0) { -- ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); -+ ASN1err(ASN1_F_ASN1_ITEM_VERIFY_CTX, ERR_R_EVP_LIB); - goto err; - } - ret = 1; - err: - OPENSSL_clear_free(buf_in, inll); -- EVP_MD_CTX_free(ctx); - return ret; - } -diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c -index cc0a59ca4c8b..39ec481ce46c 100644 ---- a/crypto/asn1/asn1_err.c -+++ b/crypto/asn1/asn1_err.c -@@ -60,6 +60,8 @@ static const ERR_STRING_DATA ASN1_str_functs[] = { - "ASN1_item_sign_ctx"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_UNPACK, 0), "ASN1_item_unpack"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_VERIFY, 0), "ASN1_item_verify"}, -+ {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_ITEM_VERIFY_CTX, 0), -+ "ASN1_item_verify_ctx"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_MBSTRING_NCOPY, 0), - "ASN1_mbstring_ncopy"}, - {ERR_PACK(ERR_LIB_ASN1, ASN1_F_ASN1_OBJECT_NEW, 0), "ASN1_OBJECT_new"}, -diff --git a/crypto/asn1/d2i_pu.c b/crypto/asn1/d2i_pu.c -index 8327ac16ca9c..e166a6da9ed8 100644 ---- a/crypto/asn1/d2i_pu.c -+++ b/crypto/asn1/d2i_pu.c -@@ -56,6 +56,9 @@ EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, - break; - #endif - #ifndef OPENSSL_NO_EC -+# ifndef OPENSSL_NO_SM2 -+ case EVP_PKEY_SM2: -+# endif - case EVP_PKEY_EC: - if (!o2i_ECPublicKey(&ret->pkey.ec, pp, length)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); -diff --git a/crypto/asn1/i2d_pu.c b/crypto/asn1/i2d_pu.c -index 8986c43cbee5..18b9f3070c72 100644 ---- a/crypto/asn1/i2d_pu.c -+++ b/crypto/asn1/i2d_pu.c -@@ -28,6 +28,9 @@ int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) - return i2d_DSAPublicKey(EVP_PKEY_get0_DSA(a), pp); - #endif - #ifndef OPENSSL_NO_EC -+# ifndef OPENSSL_NO_SM2 -+ case EVP_PKEY_SM2: -+# endif - case EVP_PKEY_EC: - return i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY(a), pp); - #endif -diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c -index 5098bd7a6602..71339aaa9e4e 100644 ---- a/crypto/ec/ec_ameth.c -+++ b/crypto/ec/ec_ameth.c -@@ -94,7 +94,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) - penclen = i2o_ECPublicKey(ec_key, &p); - if (penclen <= 0) - goto err; -- if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), -+ if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_id(pkey)), - ptype, pval, penc, penclen)) - return 1; - err: -diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c -index c423ff11d416..f82ff46a1f1d 100644 ---- a/crypto/ec/ec_curve.c -+++ b/crypto/ec/ec_curve.c -@@ -236,6 +236,45 @@ static const struct { - } - }; - -+#ifndef OPENSSL_NO_SM2 -+static const struct { -+ EC_CURVE_DATA h; -+ unsigned char data[0 + 32 * 6]; -+} _EC_sm2p256v1 = { -+ { -+ NID_X9_62_prime_field, 0, 32, 1 -+ }, -+ { -+ /* no seed */ -+ -+ /* p */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ /* a */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, -+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, -+ /* b */ -+ 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, -+ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, -+ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93, -+ /* x */ -+ 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, -+ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, -+ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7, -+ /* y */ -+ 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, -+ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, -+ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0, -+ /* order */ -+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -+ 0xff, 0xff, 0xff, 0xff, 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b, -+ 0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23, -+ } -+}; -+#endif /* OPENSSL_NO_SM2 */ -+ - typedef struct _ec_list_element_st { - int nid; - int fips_allowed; -@@ -285,6 +324,10 @@ static const ec_list_element curve_list[] = { - 0, - #endif - "X9.62/SECG curve over a 256 bit prime field"}, -+#ifndef OPENSSL_NO_SM2 -+ {NID_sm2, 0, &_EC_sm2p256v1.h, 0, -+ "SM2 curve over a 256 bit prime field"}, -+#endif - }; - - #define curve_list_length OSSL_NELEM(curve_list) -diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt -index b10dc8daa772..c9c8d542dd31 100644 ---- a/crypto/err/openssl.txt -+++ b/crypto/err/openssl.txt -@@ -45,6 +45,7 @@ ASN1_F_ASN1_ITEM_SIGN:195:ASN1_item_sign - ASN1_F_ASN1_ITEM_SIGN_CTX:220:ASN1_item_sign_ctx - ASN1_F_ASN1_ITEM_UNPACK:199:ASN1_item_unpack - ASN1_F_ASN1_ITEM_VERIFY:197:ASN1_item_verify -+ASN1_F_ASN1_ITEM_VERIFY_CTX:200:ASN1_item_verify_ctx - ASN1_F_ASN1_MBSTRING_NCOPY:122:ASN1_mbstring_ncopy - ASN1_F_ASN1_OBJECT_NEW:123:ASN1_OBJECT_new - ASN1_F_ASN1_OUTPUT_DATA:214:asn1_output_data -diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c -index 586b74605cbd..e9b907b448b2 100644 ---- a/crypto/evp/evp_pkey.c -+++ b/crypto/evp/evp_pkey.c -@@ -49,6 +49,17 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8) - goto error; - } - -+#ifndef OPENSSL_NO_SM2 -+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { -+ EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); -+ if (eckey) { -+ const EC_GROUP *group = EC_KEY_get0_group(eckey); -+ if (group && EC_GROUP_get_curve_name(group) == NID_sm2) -+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); -+ } -+ } -+#endif -+ - return pkey; - - error: -diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h -index bf0509f63d08..e669ca6b9b75 100644 ---- a/crypto/objects/obj_dat.h -+++ b/crypto/objects/obj_dat.h -@@ -10,7 +10,7 @@ - */ - - /* Serialized OID's */ --static const unsigned char so[7762] = { -+static const unsigned char so[7770] = { - 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ -@@ -1076,9 +1076,10 @@ static const unsigned char so[7762] = { - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */ -+ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7761] OBJ_SM2_with_SM3 */ - }; - --#define NUM_NID 1205 -+#define NUM_NID 1206 - static const ASN1_OBJECT nid_objs[NUM_NID] = { - {"UNDEF", "undefined", NID_undef}, - {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, -@@ -2285,9 +2286,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { - {"modp_4096", "modp_4096", NID_modp_4096}, - {"modp_6144", "modp_6144", NID_modp_6144}, - {"modp_8192", "modp_8192", NID_modp_8192}, -+ {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7761]}, - }; - --#define NUM_SN 1196 -+#define NUM_SN 1197 - static const unsigned int sn_objs[NUM_SN] = { - 364, /* "AD_DVCS" */ - 419, /* "AES-128-CBC" */ -@@ -2555,6 +2557,7 @@ static const unsigned int sn_objs[NUM_SN] = { - 1100, /* "SHAKE128" */ - 1101, /* "SHAKE256" */ - 1172, /* "SM2" */ -+ 1205, /* "SM2-SM3" */ - 1143, /* "SM3" */ - 1134, /* "SM4-CBC" */ - 1137, /* "SM4-CFB" */ -@@ -3487,7 +3490,7 @@ static const unsigned int sn_objs[NUM_SN] = { - 1093, /* "x509ExtAdmission" */ - }; - --#define NUM_LN 1196 -+#define NUM_LN 1197 - static const unsigned int ln_objs[NUM_LN] = { - 363, /* "AD Time Stamping" */ - 405, /* "ANSI X9.62" */ -@@ -3643,6 +3646,7 @@ static const unsigned int ln_objs[NUM_LN] = { - 1119, /* "RSA-SHA3-512" */ - 188, /* "S/MIME" */ - 167, /* "S/MIME Capabilities" */ -+ 1205, /* "SM2-with-SM3" */ - 1006, /* "SNILS" */ - 387, /* "SNMPv2" */ - 1025, /* "SSH Client" */ -@@ -4687,7 +4691,7 @@ static const unsigned int ln_objs[NUM_LN] = { - 125, /* "zlib compression" */ - }; - --#define NUM_OBJ 1071 -+#define NUM_OBJ 1072 - static const unsigned int obj_objs[NUM_OBJ] = { - 0, /* OBJ_undef 0 */ - 181, /* OBJ_iso 1 */ -@@ -5156,6 +5160,7 @@ static const unsigned int obj_objs[NUM_OBJ] = { - 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ - 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ - 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ -+ 1205, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ - 1144, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ - 776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ - 777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ -diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num -index ecccb9ad0b65..e60e73dbf368 100644 ---- a/crypto/objects/obj_mac.num -+++ b/crypto/objects/obj_mac.num -@@ -1202,3 +1202,4 @@ modp_3072 1201 - modp_4096 1202 - modp_6144 1203 - modp_8192 1204 -+SM2_with_SM3 1205 -diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h -index 5c3561ab7d7e..5c15ccc9ff7b 100644 ---- a/crypto/objects/obj_xref.h -+++ b/crypto/objects/obj_xref.h -@@ -79,6 +79,7 @@ static const nid_triple sigoid_srt[] = { - {NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption}, - {NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption}, - {NID_RSA_SHA3_512, NID_sha3_512, NID_rsaEncryption}, -+ {NID_SM2_with_SM3, NID_sm3, NID_sm2}, - }; - - static const nid_triple *const sigoid_srt_xref[] = { -@@ -125,4 +126,5 @@ static const nid_triple *const sigoid_srt_xref[] = { - &sigoid_srt[45], - &sigoid_srt[46], - &sigoid_srt[47], -+ &sigoid_srt[48], - }; -diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt -index ca3e74461d6c..f3dd8ed31808 100644 ---- a/crypto/objects/obj_xref.txt -+++ b/crypto/objects/obj_xref.txt -@@ -64,3 +64,5 @@ dhSinglePass_cofactorDH_sha224kdf_scheme sha224 dh_cofactor_kdf - dhSinglePass_cofactorDH_sha256kdf_scheme sha256 dh_cofactor_kdf - dhSinglePass_cofactorDH_sha384kdf_scheme sha384 dh_cofactor_kdf - dhSinglePass_cofactorDH_sha512kdf_scheme sha512 dh_cofactor_kdf -+ -+SM2_with_SM3 sm3 sm2 -diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt -index c2721a1d5fa7..38aa8db5fe13 100644 ---- a/crypto/objects/objects.txt -+++ b/crypto/objects/objects.txt -@@ -383,6 +383,7 @@ rsadsi 2 7 : : hmacWithSHA1 - sm-scheme 301 : SM2 : sm2 - - sm-scheme 401 : SM3 : sm3 -+sm-scheme 501 : SM2-SM3 : SM2-with-SM3 - sm-scheme 504 : RSA-SM3 : sm3WithRSAEncryption - - # From RFC4231 -diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c -index 086386ee4ecd..a94b3adf78e9 100644 ---- a/crypto/sm2/sm2_pmeth.c -+++ b/crypto/sm2/sm2_pmeth.c -@@ -220,6 +220,10 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) - *(size_t *)p2 = smctx->id_len; - return 1; - -+ case EVP_PKEY_CTRL_PEER_KEY: -+ case EVP_PKEY_CTRL_PKCS7_SIGN: -+ case EVP_PKEY_CTRL_CMS_SIGN: -+ /* Default behaviour is OK */ - case EVP_PKEY_CTRL_DIGESTINIT: - /* nothing to be inited, this is to suppress the error... */ - return 1; -@@ -252,6 +256,25 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx, - else - return -2; - return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); -+ } else if (strcmp(type, "distid") == 0) { -+ SM2_PKEY_CTX *smctx = ctx->data; -+ -+ OPENSSL_free(smctx->id); -+ -+ if (value) { -+ smctx->id = (uint8_t *)OPENSSL_strdup(value); -+ if (smctx->id == NULL) { -+ SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ smctx->id_len = OPENSSL_strnlen(value, SIZE_MAX); -+ } else { -+ /* set null-ID */ -+ smctx->id = NULL; -+ smctx->id_len = 0; -+ } -+ smctx->id_set = 1; -+ return 1; - } - - return -2; -@@ -267,12 +290,22 @@ static int pkey_sm2_digest_custom(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) - - if (!smctx->id_set) { - /* -- * An ID value must be set. The specifications are not clear whether a -- * NULL is allowed. We only allow it if set explicitly for maximum -- * flexibility. -+ * Actually, there is no standard doc which illustrate how to set sm2-id -+ * correctly, only GM/T 0009-2012 gives a fuzzy definition that sm2-id -+ * would be "1234567812345678", and there is no way to get sm2-id from -+ * certificate. In tls handshake, client/server would get a long -+ * certificate chain from peer, we can't find any effective way to -+ * recognize or set sm2-id for each cert, so we choose to set a default -+ * sm2 id for each sm2 sign process. - */ -- SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, SM2_R_ID_NOT_SET); -- return 0; -+ smctx->id = (uint8_t *)OPENSSL_memdup(SM2_DEFAULT_USERID, -+ SM2_DEFAULT_USERID_LEN); -+ if (smctx->id == NULL) { -+ SM2err(SM2_F_PKEY_SM2_DIGEST_CUSTOM, ERR_R_MALLOC_FAILURE); -+ return 0; -+ } -+ smctx->id_len = SM2_DEFAULT_USERID_LEN; -+ smctx->id_set = 1; - } - - if (mdlen < 0) { -diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c -index a4e9cdaee837..9ec04d87b405 100644 ---- a/crypto/x509/x_all.c -+++ b/crypto/x509/x_all.c -@@ -27,12 +27,27 @@ int X509_verify(X509 *a, EVP_PKEY *r) - &a->signature, &a->cert_info, r)); - } - -+int X509_verify_ctx(X509 *a, EVP_PKEY *r, EVP_MD_CTX *ctx) -+{ -+ if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature)) -+ return 0; -+ return (ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg, -+ &a->signature, &a->cert_info, r, ctx)); -+} -+ - int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) - { - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), - &a->sig_alg, a->signature, &a->req_info, r)); - } - -+int X509_REQ_verify_ctx(X509_REQ *a, EVP_PKEY *r, EVP_MD_CTX *ctx) -+{ -+ return (ASN1_item_verify_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), -+ &a->sig_alg, a->signature, &a->req_info, r, -+ ctx)); -+} -+ - int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) - { - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), -diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c -index 9be7e9286571..43b40ffd9fc1 100644 ---- a/crypto/x509/x_pubkey.c -+++ b/crypto/x509/x_pubkey.c -@@ -130,6 +130,17 @@ static int x509_pubkey_decode(EVP_PKEY **ppkey, X509_PUBKEY *key) - goto error; - } - -+#ifndef OPENSSL_NO_SM2 -+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { -+ EC_KEY *eckey = EVP_PKEY_get0_EC_KEY(pkey); -+ if (eckey) { -+ const EC_GROUP *group = EC_KEY_get0_group(eckey); -+ if (group && EC_GROUP_get_curve_name(group) == NID_sm2) -+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2); -+ } -+ } -+#endif -+ - *ppkey = pkey; - return 1; - -diff --git a/fuzz/oids.txt b/fuzz/oids.txt -index eda55e4e792c..8dfdea9552ef 100644 ---- a/fuzz/oids.txt -+++ b/fuzz/oids.txt -@@ -1063,3 +1063,4 @@ OBJ_id_tc26_gost_3410_2012_256_paramSetC="\x2A\x85\x03\x07\x01\x02\x01\x01\x03" - OBJ_id_tc26_gost_3410_2012_256_paramSetD="\x2A\x85\x03\x07\x01\x02\x01\x01\x04" - OBJ_hmacWithSHA512_224="\x2A\x86\x48\x86\xF7\x0D\x02\x0C" - OBJ_hmacWithSHA512_256="\x2A\x86\x48\x86\xF7\x0D\x02\x0D" -+OBJ_SM2_with_SM3="\x2A\x81\x1C\xCF\x55\x01\x83\x75" -diff --git a/include/crypto/sm2.h b/include/crypto/sm2.h -index 76ee80baff19..51e20af7eff9 100644 ---- a/include/crypto/sm2.h -+++ b/include/crypto/sm2.h -@@ -19,6 +19,7 @@ - - /* The default user id as specified in GM/T 0009-2012 */ - # define SM2_DEFAULT_USERID "1234567812345678" -+# define SM2_DEFAULT_USERID_LEN (sizeof(SM2_DEFAULT_USERID) - 1) - - int sm2_compute_z_digest(uint8_t *out, - const EVP_MD *digest, -diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h -index e1ad1fefeca7..7eadd76492cd 100644 ---- a/include/openssl/asn1err.h -+++ b/include/openssl/asn1err.h -@@ -60,6 +60,7 @@ int ERR_load_ASN1_strings(void); - # define ASN1_F_ASN1_ITEM_SIGN_CTX 220 - # define ASN1_F_ASN1_ITEM_UNPACK 199 - # define ASN1_F_ASN1_ITEM_VERIFY 197 -+# define ASN1_F_ASN1_ITEM_VERIFY_CTX 200 - # define ASN1_F_ASN1_MBSTRING_NCOPY 122 - # define ASN1_F_ASN1_OBJECT_NEW 123 - # define ASN1_F_ASN1_OUTPUT_DATA 214 -diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h -index 9029906a326a..d0dc18511cb9 100644 ---- a/include/openssl/obj_mac.h -+++ b/include/openssl/obj_mac.h -@@ -1174,6 +1174,11 @@ - #define NID_sm3 1143 - #define OBJ_sm3 OBJ_sm_scheme,401L - -+#define SN_SM2_with_SM3 "SM2-SM3" -+#define LN_SM2_with_SM3 "SM2-with-SM3" -+#define NID_SM2_with_SM3 1205 -+#define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L -+ - #define SN_sm3WithRSAEncryption "RSA-SM3" - #define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" - #define NID_sm3WithRSAEncryption 1144 -diff --git a/include/openssl/x509.h b/include/openssl/x509.h -index 3ff86ec7b54d..19469227c5a9 100644 ---- a/include/openssl/x509.h -+++ b/include/openssl/x509.h -@@ -348,8 +348,10 @@ void *X509_CRL_get_meth_data(X509_CRL *crl); - const char *X509_verify_cert_error_string(long n); - - int X509_verify(X509 *a, EVP_PKEY *r); -+int X509_verify_ctx(X509 *a, EVP_PKEY *r, EVP_MD_CTX *ctx); - - int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); -+int X509_REQ_verify_ctx(X509_REQ *a, EVP_PKEY *r, EVP_MD_CTX *ctx); - int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); - int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); - -@@ -624,6 +626,9 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, - - int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); -+int ASN1_item_verify_ctx(const ASN1_ITEM *it, X509_ALGOR *a, -+ ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, -+ EVP_MD_CTX *ctx); - - int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, -diff --git a/util/libcrypto.num b/util/libcrypto.num -index f1c12c3ed096..7e66104cda97 100644 ---- a/util/libcrypto.num -+++ b/util/libcrypto.num -@@ -4634,3 +4634,6 @@ EVP_KDF_vctrl 6594 1_1_1b EXIST::FUNCTION: - EVP_KDF_ctrl_str 6595 1_1_1b EXIST::FUNCTION: - EVP_KDF_size 6596 1_1_1b EXIST::FUNCTION: - EVP_KDF_derive 6597 1_1_1b EXIST::FUNCTION: -+ASN1_item_verify_ctx 6700 1_1_1k EXIST::FUNCTION: -+X509_verify_ctx 6701 1_1_1k EXIST::FUNCTION: -+X509_REQ_verify_ctx 6702 1_1_1k EXIST::FUNCTION: --- -2.24.3 (Apple Git-128) - diff --git a/openssl.spec b/openssl.spec index 4d76f761c1d172ec3a80ffe907d9458b2379a655..007118d3ca4838d5324db300f2c7eeeedc197766 100644 --- a/openssl.spec +++ b/openssl.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.2 +%define anolis_release .0.1 # For the curious: # 0.9.5a soversion = 0 # 0.9.6 soversion = 1 @@ -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: 9%{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. @@ -88,8 +88,11 @@ Patch83: openssl-1.1.1-replace-expired-certs.patch Patch84: openssl-1.1.1-cve-2022-1292.patch 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.patch +Patch102: openssl-1.1.1-cve-2022-4450-PEM-bio.patch +Patch103: openssl-1.1.1-cve-2023-0215-BIO-UAF.patch +Patch104: openssl-1.1.1-cve-2023-0286-X400.patch License: OpenSSL and ASL 2.0 URL: http://www.openssl.org/ @@ -215,7 +218,10 @@ cp %{SOURCE13} test/ %patch84 -p1 -b .cve-2022-1292 %patch85 -p1 -b .cve-2022-2068 %patch86 -p1 -b .cve-2022-2097 -%patch87 -p1 -b .sm2-sign-verify +%patch101 -p1 -b .cve-2022-4304 +%patch102 -p1 -b .cve-2022-4450 +%patch103 -p1 -b .cve-2023-0215 +%patch104 -p1 -b .cve-2023-0286 %build # Figure out which flags we want to use. @@ -300,7 +306,7 @@ export HASHBANGPERL=/usr/bin/perl zlib enable-camellia enable-seed enable-rfc3779 enable-sctp \ enable-cms enable-md2 enable-rc5\ enable-weak-ssl-ciphers \ - no-mdc2 no-ec2m \ + no-mdc2 no-ec2m no-sm2 no-sm4 \ shared ${sslarch} $RPM_OPT_FLAGS '-DDEVRANDOM="\"/dev/urandom\""' # Do not run this in a production package the FIPS symbols must be patched-in @@ -504,25 +510,36 @@ export LD_LIBRARY_PATH %postun libs -p /sbin/ldconfig %changelog -* Mon Nov 28 2022 Tianjia Zhang - 1:1.1.1k-7.0.2 -- Support SM2 distid for sign and verify - -* Thu Aug 04 2022 Liwei Ge - 1:1.1.1k-7.0.1 +* Thu Mar 23 2023 Liwei Ge - 1:1.1.1k-9.0.1 - Support loongarch64 +* Wed Feb 08 2023 Dmitry Belyavskiy - 1:1.1.1k-9 +- Fixed Timing Oracle in RSA Decryption + Resolves: CVE-2022-4304 +- Fixed Double free after calling PEM_read_bio_ex + Resolves: CVE-2022-4450 +- Fixed Use-after-free following BIO_new_NDEF + Resolves: CVE-2023-0215 +- Fixed X.400 address type confusion in X.509 GeneralName + Resolves: CVE-2023-0286 + +* Thu Jul 21 2022 Dmitry Belyavskiy - 1:1.1.1k-8 +- Fix no-ec build + Resolves: rhbz#2071020 + * Tue Jul 05 2022 Clemens Lang - 1:1.1.1k-7 - Fix CVE-2022-2097: AES OCB fails to encrypt some bytes on 32-bit x86 Resolves: CVE-2022-2097 - Update expired certificates used in the testsuite - Resolves: rhbz#2100554 + Resolves: rhbz#2092462 - Fix CVE-2022-1292: openssl: c_rehash script allows command injection - Resolves: rhbz#2090371 + Resolves: rhbz#2090372 - Fix CVE-2022-2068: the c_rehash script allows command injection - Resolves: rhbz#2098278 + Resolves: rhbz#2098279 * Wed Mar 23 2022 Clemens Lang - 1:1.1.1k-6 - Fixes CVE-2022-0778 openssl: Infinite loop in BN_mod_sqrt() reachable when parsing certificates -- Resolves: rhbz#2067145 +- Resolves: rhbz#2067146 * Tue Nov 16 2021 Sahana Prasad - 1:1.1.1k-5 - Fixes CVE-2021-3712 openssl: Read buffer overruns processing ASN.1 strings