Index: /branches/rel_ag_9_4_5/Makefile
===================================================================
--- /branches/rel_ag_9_4_5/Makefile	(revision 20526)
+++ /branches/rel_ag_9_4_5/Makefile	(working copy)
@@ -19,6 +19,7 @@
 SubDir += kernelapi
 SubDir += fastlog
 SubDir += ssl
+SubDir += ssl-111
 SubDir += lib
 SubDir += python
 SubDir += englog
@@ -110,6 +111,7 @@
 cmSubDir += kernelapi
 cmSubDir += fastlog
 cmSubDir += ssl
+cmSubDir += ssl-111
 cmSubDir += lib
 cmSubDir += python
 cmSubDir += englog
Index: /branches/rel_ag_9_4_5/ssl-111/Makefile
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/Makefile	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/Makefile	(working copy)
@@ -0,0 +1,83 @@
+TOP=..
+include $(TOP)/Makefile.master
+
+OPENSSL_PKG=openssl-1.1.1d
+OPENSSL_OPT=no-idea no-rc5 shared threads no-sse2
+OPENSSL_LIB=openssl/libcrypto.so.1.1 openssl/libssl.so.1.1
+OPENSSL_INC=openssl/include/openssl
+OPENSSL_APP=openssl/apps/openssl
+
+PATCH1=openssl-1.1.1d-4cert.patch
+PATCH2=openssl-1.1.1d-sm2.patch
+PATCH3=openssl-1.1.1d-bug93451.patch
+PATCH4=openssl-1.1.1d-bug94818.patch
+PATCH5=openssl-1.1.1d-4hc.patch
+PATCH6=openssl-1.1.1d-bug94781.patch
+PATCH7=openssl-1.1.1d-bug95954.patch
+PATCH8=openssl-1.1.1d-bug94844.patch
+PATCH9=openssl-1.1.1d-bug100709.patch
+PATCH10=openssl-1.1.1d-bug93700.patch
+PATCH11=openssl-1.1.1d-bug105409.patch
+PATCH12=openssl-1.1.1d-cve-2021-23841.patch
+PATCH13=openssl-1.1.1d-bug109332.patch
+PATCH14=sm4_gcm_ccm.patch
+PATCH15=openssl-1.1.1d-CVE-2022-0778.patch
+PATCH16=ocsp_retry.patch
+#PATCHx=openssl-1.1.1d-bug102140.patch
+
+INST_LIB= $(OPENSSL_LIB)
+
+
+$(OPENSSL_APP) $(OPENSSL_LIB): $(OPENSSL_INC)
+# all: $(OPENSSL_INC)
+	cd openssl && make && cd ..;
+	sh copy_header.sh;
+
+$(OPENSSL_INC)::
+.if !exists ($(OPENSSL_PKG))
+	sh install_perl5.10.1.sh
+	tar -zxf $(OPENSSL_PKG).tar.gz;
+	$(RM) -rf openssl;
+	ln -sf $(OPENSSL_PKG) openssl;
+
+	@echo "PWD+ca_root = $(PWD)/../$(CA_ROOT)";
+	cd openssl && \
+	patch -p1 < ../d_patch/$(PATCH1) && \
+	patch -p1 < ../d_patch/$(PATCH2) && \
+	patch -p1 < ../d_patch/$(PATCH3) && \
+	patch -p1 < ../d_patch/$(PATCH4) && \
+	patch -p1 < ../d_patch/$(PATCH5) && \
+	patch -p1 < ../d_patch/$(PATCH6) && \
+	patch -p1 < ../d_patch/$(PATCH7) && \
+	patch -p1 < ../d_patch/$(PATCH8) && \
+	patch -p1 < ../d_patch/$(PATCH9) && \
+	patch -p1 < ../d_patch/$(PATCH10) && \
+	patch -p1 < ../d_patch/$(PATCH11) && \
+	patch -p1 < ../d_patch/$(PATCH12) && \
+	patch -p1 < ../d_patch/$(PATCH13) && \
+	patch -p1 < ../d_patch/$(PATCH14) && \
+	patch -p1 < ../d_patch/$(PATCH15) && \
+	patch -p1 < ../d_patch/$(PATCH16);
+	cd openssl && \
+	/usr/local/bin/perl5.10.1 Configure BSD-x86_64 --prefix=$(PWD)/../$(CA_ROOT) --openssldir=$(PWD)/../$(CA_ROOT)/ssl-111 $(OPENSSL_OPT) && \
+	cd ..;
+.endif
+.if !exists (./openssl/lib)
+	 mkdir openssl/lib;
+.endif
+.if !exists (./openssl/lib/libcrypto.a)
+	cd openssl/lib && ln -s ../libcrypto.a;
+.endif
+.if !exists (./openssl/lib/libssl.a)
+	cd openssl/lib && ln -s ../libssl.a;
+.endif
+
+clean::
+	$(RM) -f *.o *.a
+.ifndef SAFE
+	$(RM) -rf openssl;
+	$(RM) -rf perl-5.10.1;
+	$(RM) -rf $(OPENSSL_PKG);
+.endif
+
+include $(TOP)/Makefile.install1
\ No newline at end of file
Index: /branches/rel_ag_9_4_5/ssl-111/copy_header.sh
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/copy_header.sh	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/copy_header.sh	(working copy)
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+OPENSSL_NAME=openssl-1.1.1d
+
+
+# cd ${OPENSSL_NAME} #/usr/home/peter/rel_ag_9_4_5_tlsv13/ssl-111/openssl-1.1.1d
+
+rm -rf include
+mkdir -p include/openssl/internal
+cp -rf ${OPENSSL_NAME}/include/openssl/* include/openssl/
+cp -rf ${OPENSSL_NAME}/include/internal/* include/openssl/internal/
+cp -rf ${OPENSSL_NAME}/e_os.h include/openssl/
+find ${OPENSSL_NAME}/crypto -name "*.h" -exec cp -f {} include/openssl/internal/ \;
+find ${OPENSSL_NAME}/ssl -name "*.h" -exec cp -f {} include/openssl/internal/ \;
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/ocsp_retry.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/ocsp_retry.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/ocsp_retry.patch	(working copy)
@@ -0,0 +1,20 @@
+diff -uNa -r -r openssl-1.1.1d-old/crypto/ocsp/ocsp_ht.c openssl-1.1.1d/crypto/ocsp/ocsp_ht.c
+--- openssl-1.1.1d-old/crypto/ocsp/ocsp_ht.c	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/crypto/ocsp/ocsp_ht.c	2022-10-19 00:15:17.583156160 +0800
+@@ -483,6 +483,7 @@
+     OCSP_RESPONSE *resp = NULL;
+     OCSP_REQ_CTX *ctx;
+     int rv;
++    int retry_count = 0;
+ 
+     ctx = OCSP_sendreq_new(b, path, req, -1);
+ 
+@@ -491,7 +492,7 @@
+ 
+     do {
+         rv = OCSP_sendreq_nbio(&resp, ctx);
+-    } while ((rv == -1) && BIO_should_retry(b));
++    } while ((rv == -1) && BIO_should_retry(b) && retry_count++ < 2);
+ 
+     OCSP_REQ_CTX_free(ctx);
+ 
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4cert.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4cert.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4cert.patch	(working copy)
@@ -0,0 +1,951 @@
+diff --git a/apps/openssl.cnf b/apps/openssl.cnf
+index 4acca4b..d69b0ad 100644
+--- a/apps/openssl.cnf
++++ b/apps/openssl.cnf
+@@ -148,7 +148,7 @@ organizationalUnitName		= Organizational Unit Name (eg, section)
+ #organizationalUnitName_default	=
+ 
+ commonName			= Common Name (e.g. server FQDN or YOUR name)
+-commonName_max			= 64
++commonName_max			= 128
+ 
+ emailAddress			= Email Address
+ emailAddress_max		= 64
+diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c
+index ea4dd1c..18b7850 100644
+--- a/crypto/asn1/a_strex.c
++++ b/crypto/asn1/a_strex.c
+@@ -17,6 +17,10 @@
+ 
+ #include "charmap.h"
+ 
++#include <sys/queue.h>
++#include <stdarg.h>
++#include "internal/x509_int.h"
++
+ /*
+  * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name
+  * printing routines handling multibyte characters, RFC2253 and a host of
+@@ -126,6 +130,59 @@ static int do_esc_char(unsigned long c, unsigned short flags, char *do_quotes,
+     return 1;
+ }
+ 
++/* Bug 15936, chenyl, 20070329 */
++/* copy from do_esc_char, change "\\" to "%%" */
++static int do_esc_char_for_certm(unsigned long c, unsigned char flags, char *do_quotes, 
++				 char_io *io_ch, void *arg)
++{
++        unsigned char chflgs, chtmp;
++        char tmphex[HEX_SIZE(long)+3];
++
++        if(c > 0xffffffffL)     
++                return -1;      
++        if(c > 0xffff) {
++                BIO_snprintf(tmphex, sizeof tmphex, "%%W%08lX", c);
++                if(!io_ch(arg, tmphex, 10)) return -1; 
++                return 10;
++        }               
++        if(c > 0xff) {  
++                BIO_snprintf(tmphex, sizeof tmphex, "%%U%04lX", c);
++                if(!io_ch(arg, tmphex, 6)) return -1;
++                return 6;
++        }
++        chtmp = (unsigned char)c;
++
++        /* add for bug 15936 */
++        if('%' == chtmp) {
++                BIO_snprintf(tmphex, 11, "%%%02X", chtmp);
++                if(!io_ch(arg, tmphex, 3)) return -1;
++                return 3;
++        }
++        /* add end */
++
++        if(chtmp > 0x7f) chflgs = flags & ASN1_STRFLGS_ESC_MSB;
++        else chflgs = char_type[chtmp] & flags;
++        if(chflgs & CHARTYPE_BS_ESC) {
++                /* If we don't escape with quotes, signal we need quotes */
++                if(chflgs & ASN1_STRFLGS_ESC_QUOTE) {
++                        if(do_quotes) *do_quotes = 1;
++                        if(!io_ch(arg, &chtmp, 1)) return -1;
++                        return 1;
++                }
++                if(!io_ch(arg, "\\", 1)) return -1;
++                if(!io_ch(arg, &chtmp, 1)) return -1;
++                return 2;
++        }
++        if(chflgs & ASN1_STRFLGS_ESC_CTRL) {	/*Bug 24526, chenhb, 20100226*/
++                BIO_snprintf(tmphex, 11, "%%%02X", chtmp);
++                if(!io_ch(arg, tmphex, 3)) return -1;
++                return 3;
++        }
++        if(!io_ch(arg, &chtmp, 1)) return -1;
++        return 1;
++}
++/* Bug 15936, end */
++
+ #define BUF_TYPE_WIDTH_MASK     0x7
+ #define BUF_TYPE_CONVUTF8       0x8
+ 
+@@ -229,6 +286,70 @@ static int do_buf(unsigned char *buf, int buflen,
+     return outlen;
+ }
+ 
++/* Bug 15936, chenyl, 20070329 */
++/* copy from do_buf, call function do_esc_char_for_certm instead of do_esc_char */
++static int do_buf_for_certm(unsigned char *buf, int buflen,
++                        int type, unsigned char flags, char *quotes, char_io *io_ch, void *arg)
++{
++        int i, outlen, len;
++        unsigned char orflags, *p, *q;
++        unsigned long c;
++        p = buf;
++        q = buf + buflen;
++        outlen = 0;
++        while(p != q) {
++                if(p == buf) orflags = CHARTYPE_FIRST_ESC_2253;
++                else orflags = 0;
++                switch(type & BUF_TYPE_WIDTH_MASK) {
++                        case 4:        
++	                 c = ((unsigned long)*p++) << 24;
++                        c |= ((unsigned long)*p++) << 16;
++                        c |= ((unsigned long)*p++) << 8;
++                        c |= *p++;
++                        break;
++
++                        case 2:
++                        c = ((unsigned long)*p++) << 8;
++                        c |= *p++;
++                        break;
++
++                        case 1:
++                        c = *p++;
++                        break;
++
++                        case 0:
++                        i = UTF8_getc(p, buflen, &c);
++                        if(i < 0) return -1;    /* Invalid UTF8String */
++                        p += i;
++                        break;
++                        default:
++                        return -1;      /* invalid width */
++                }
++                if (p == q) orflags = CHARTYPE_LAST_ESC_2253;
++                if(type & BUF_TYPE_CONVUTF8) {
++                        unsigned char utfbuf[6];
++                        int utflen;
++			utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
++			for(i = 0; i < utflen; i++) {
++				/* We don't need to worry about setting orflags correctly
++				 * because if utflen==1 its value will be correct anyway 
++                                 * otherwise each character will be > 0x7f and so the 
++	                         * character will never be escaped on first and last.
++			        */
++				len = do_esc_char_for_certm(utfbuf[i], (unsigned char)(flags | orflags), quotes, io_ch, arg);
++				if(len < 0) return -1;
++				outlen += len;
++			}
++		} else {
++                        len = do_esc_char_for_certm(c, (unsigned char)(flags | orflags), quotes, io_ch, arg);
++                        if(len < 0) return -1;
++                        outlen += len;
++                }
++        }
++        return outlen;
++}
++/* Bug 15936, end */
++
+ /* This function hex dumps a buffer of characters */
+ 
+ static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
+@@ -405,6 +526,79 @@ static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
+     return outlen;
+ }
+ 
++/* Bug 15936, chenyl, 20070329 */
++/* copy from do_print_ex, call function do_buf_for_certm instead of do_buf */
++static int do_print_ex_for_certm(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
++{
++        int outlen, len;
++        int type;
++        char quotes;
++        unsigned char flags;
++
++        if (str == NULL) {
++        	return 0;
++        }
++
++        quotes = 0;
++        /* Keep a copy of escape flags */
++        flags = (unsigned char)(lflags & ESC_FLAGS);
++
++        type = str->type;
++
++        outlen = 0;
++
++
++        if(lflags & ASN1_STRFLGS_SHOW_TYPE) {
++                const char *tagname;
++                tagname = ASN1_tag2str(type);
++                outlen += strlen(tagname);
++                if(!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) return -1;
++                outlen++;
++        }
++
++        /* Decide what to do with type, either dump content or display it */
++
++        /* Dump everything */
++        if(lflags & ASN1_STRFLGS_DUMP_ALL) type = -1;
++        /* Ignore the string type */
++        else if(lflags & ASN1_STRFLGS_IGNORE_TYPE) type = 1;
++        else {
++                /* Else determine width based on type */
++                if((type > 0) && (type < 31)) type = tag2nbyte[type];
++                else type = -1;
++                if((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) type = 1;
++        }
++
++        if(type == -1) {
++                len = do_dump(lflags, io_ch, arg, str);
++                if(len < 0) return -1;
++                outlen += len;
++                return outlen;
++        }
++
++        if(lflags & ASN1_STRFLGS_UTF8_CONVERT) {
++		/* Note: if string is UTF8 and we want
++		 * to convert to UTF8 then we just interpret
++		 * it as 1 byte per character to avoid converting
++		 * twice.
++		 */
++		if(!type) type = 1;
++		else type |= BUF_TYPE_CONVUTF8;
++        }
++
++        len = do_buf_for_certm(str->data, str->length, type, flags, &quotes, io_ch, NULL);
++        if(len < 0) return -1;
++        outlen += len;
++        if(quotes) outlen += 2;
++        if(!arg) return outlen;
++        if(quotes && !io_ch(arg, "\"", 1)) return -1;
++        if(do_buf_for_certm(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
++                return -1;
++        if(quotes && !io_ch(arg, "\"", 1)) return -1;
++        return outlen;
++}
++/* Bug 15936, end */
++
+ /* Used for line indenting: print 'indent' spaces */
+ 
+ static int do_indent(char_io *io_ch, void *arg, int indent)
+@@ -555,6 +749,499 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
+     return outlen;
+ }
+ 
++/* bug 16039, lingx, 20070407 */
++typedef struct position {
++	int pos;
++	X509_NAME_ENTRY *ent;
++	TAILQ_ENTRY(position) next;
++} position_t;
++
++typedef TAILQ_HEAD(rdn_pos_tailq, position) rdn_position_t;
++
++enum {
++	EMAIL_ADDRESS = 0,	/* NID_pkcs9_emailAddress */
++	UID,			/* NID_userId */
++	TITLE,			/* NID_title */
++	COMMONNAME,		/* NID_commonName */
++	ORG_UNIT,		/* NID_organizationalUnitName */
++	ORG,			/* NIDorganizational */
++	LOCATION,		/* NID_localityName */
++	STATE,			/* NID_stateOrProvinceName */
++	CONTRY,			/* NID_contryName */
++	DC,			/* NID_domainComponent */
++	UNDEFINED,		/* NID_undef */
++	NID_MAX_COUNT
++};
++
++/* Copy from slb.h, need keep consistent */
++#define MAX_OID_NUM		18 
++#define MAX_OIDNAME_LEN		32 
++typedef struct slb_ssl_oidname_table {
++	unsigned char index;			/*Index of oid*/
++	unsigned char flag;			/*Specify if the oid changed by CLI*/
++	char oidname[MAX_OIDNAME_LEN]; 	/*The name of oid*/
++} slb_ssl_oidname_table_t;
++
++static unsigned short nid_value[] = {
++	NID_undef,
++	NID_surname,
++	NID_givenName,
++	NID_name,
++	NID_initials,
++	NID_generationQualifier,
++	NID_serialNumber,
++	NID_pkcs9_emailAddress,
++	NID_commonName,
++	NID_title,
++	NID_pseudonym,
++	NID_dnQualifier,
++	NID_organizationalUnitName,
++	NID_organizationName,
++	NID_localityName,
++	NID_stateOrProvinceName,
++	NID_domainComponent,
++	NID_countryName
++};
++
++static int 
++nid2index(nid) {
++	int i;
++	for (i=0; i<MAX_OID_NUM; i++) {
++		if (nid == nid_value[i]) {
++			return i; 	
++		}	
++	}
++	return 0;
++}	
++
++/* 
++ *  * email=uid<title<CN<{OU<O<L<S<C|dc<C}
++ *   * 48
++ *    * entry_order[] = {48, 458, 106, 13, 18, 17, 15, 16, 14, 391};
++ *     */
++static position_t *
++sort_rdn(rdn_position_t *rdn_header, X509_NAME *name, int count, int flags)	/*Bug 24526, chenhb, 20100303*/
++{
++	int i;
++	X509_NAME_ENTRY *ent;
++	ASN1_OBJECT *fn;
++	int fn_nid;
++	position_t *pos = NULL;
++
++	if (name == NULL) {
++		return NULL;
++	}
++
++	pos = (position_t *)malloc(count * sizeof(position_t));
++	if (pos == NULL) {
++		goto end;
++		return NULL;
++	}
++	bzero(pos, count * sizeof(position_t));
++
++	for (i = 0; i < count; i++) {
++		ent = X509_NAME_get_entry(name, i);
++		if (ent == NULL) {
++			continue;
++		}
++
++		fn = X509_NAME_ENTRY_get_object(ent);
++		fn_nid = OBJ_obj2nid(fn);
++
++		(pos+i)->ent = ent;
++		(pos+i)->pos = i;
++		/*Bug 24526, chenhb, 20100303*/
++		if (flags & XN_FLAG_DN_ORI) {
++			(pos+i)->pos = fn_nid;
++			TAILQ_INSERT_TAIL(&rdn_header[0], pos+i, next);
++			continue;
++		}
++		/*Bug 24526, end*/
++
++		switch (fn_nid) {
++		case NID_commonName:
++			TAILQ_INSERT_HEAD(&rdn_header[COMMONNAME], pos+i, next);
++			break;
++
++		case NID_pkcs9_emailAddress:
++			TAILQ_INSERT_HEAD(&rdn_header[EMAIL_ADDRESS], pos+i, next);
++			break;
++
++		case NID_userId:
++			TAILQ_INSERT_HEAD(&rdn_header[UID], pos+i, next);
++			break;
++
++		case NID_title:
++			TAILQ_INSERT_HEAD(&rdn_header[TITLE], pos+i, next);
++			break;
++
++		case NID_organizationalUnitName:
++			TAILQ_INSERT_HEAD(&rdn_header[ORG_UNIT], pos+i, next);
++			break;
++
++		case NID_organizationName:
++			TAILQ_INSERT_HEAD(&rdn_header[ORG], pos+i, next);
++			break;
++
++		case NID_localityName:
++			TAILQ_INSERT_HEAD(&rdn_header[LOCATION], pos+i, next);
++			break;
++
++		case NID_stateOrProvinceName:
++			TAILQ_INSERT_HEAD(&rdn_header[STATE], pos+i, next);
++			break;
++
++		case NID_countryName:
++			TAILQ_INSERT_HEAD(&rdn_header[CONTRY], pos+i, next);
++			break;
++
++		case NID_domainComponent:
++			TAILQ_INSERT_HEAD(&rdn_header[DC], pos+i, next);
++			break;
++
++		default:	/* Others will be inputed into undefined field */
++			TAILQ_INSERT_HEAD(&rdn_header[UNDEFINED], pos+i, next);
++			break;
++		}
++	}
++
++	return pos;
++
++end:
++	if (pos != NULL) {
++		free(pos);
++	}
++
++	return NULL;
++}
++
++static int
++X509_NAME_ENTRY_print(char_io *io_ch, void *arg, X509_NAME_ENTRY *ent, int fn_nid,
++                      int fn_opt, unsigned long flags, char *sep_eq, int sep_eq_len, void *poidname)
++{
++	int len;
++	int outlen = 0;
++	int orflags;
++	int index = 0;
++	char objtmp[80];
++	const char *objbuf;
++	slb_ssl_oidname_table_t *poid = NULL;
++
++	ASN1_OBJECT *fn = NULL;
++	ASN1_STRING *val = NULL;
++	
++	fn = X509_NAME_ENTRY_get_object(ent);
++	val = X509_NAME_ENTRY_get_data(ent);
++	fn_nid = OBJ_obj2nid(fn);
++	if(fn_opt != XN_FLAG_FN_NONE) {
++		int objlen, fld_len;
++		if((fn_opt == XN_FLAG_FN_OID) || (fn_nid==NID_undef) ) {
++			OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
++			fld_len = 0; /* XXX: what should this be? */
++			objbuf = objtmp;
++		} else {
++			if(fn_opt == XN_FLAG_FN_SN) {
++				fld_len = FN_WIDTH_SN;
++				if (poidname == NULL) {
++					objbuf = OBJ_nid2sn(fn_nid);
++				} else {
++					index = nid2index(fn_nid);
++					if (index != 0) {
++						poid = (slb_ssl_oidname_table_t *)(poidname + index * sizeof(slb_ssl_oidname_table_t)); 
++						strncpy(objtmp, poid->oidname, MAX_OIDNAME_LEN - 1);
++						objbuf = objtmp;
++					} else {
++						objbuf = OBJ_nid2sn(fn_nid);
++					}
++				}
++			} else if(fn_opt == XN_FLAG_FN_LN) {
++				fld_len = FN_WIDTH_LN;
++				objbuf = OBJ_nid2ln(fn_nid);
++			} else {
++				fld_len = 0; /* XXX: what should this be? */
++				objbuf = "";
++			}
++		}
++		objlen = strlen(objbuf);
++		if(!io_ch(arg, objbuf, objlen)) {
++			return -1;
++		}
++		if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
++			if (!do_indent(io_ch, arg, fld_len - objlen)) {
++				return -1;
++			}
++			outlen += fld_len - objlen;
++		}
++		if(!io_ch(arg, sep_eq, sep_eq_len)) {
++			return -1;
++		}
++		outlen += objlen + sep_eq_len;
++	}
++	/* If the field name is unknown then fix up the DER dump
++ * 	 * flag. We might want to limit this further so it will
++ * 	  	 * DER dump on anything other than a few 'standard' fields.
++ * 	  	 	 */
++	if((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) { 
++		orflags = ASN1_STRFLGS_DUMP_ALL;
++	} else {
++		orflags = 0;
++	}	
++     	len = do_print_ex_for_certm(io_ch, arg, flags | orflags, val);
++	if(len < 0) {
++		return -1;
++	}
++	outlen += len;
++	
++	return outlen; 		
++}
++/* bug 16039, end */
++
++/* Bug 17749, chenyl, 20071026 */
++static int
++check_prev_for_X509_NAME_ENTRY_print(int prev,  position_t *pos, void *arg, char *sep_mv, 
++			int sep_mv_len, char *sep_dn, int sep_dn_len, char_io *io_ch, int indent)
++{
++	int	ret = 0;
++
++	if(prev == pos->ent->set) {
++		if(!io_ch(arg, sep_mv, sep_mv_len)) {
++			return -1;
++		}
++		ret = sep_mv_len;
++	} else {
++		if(!io_ch(arg, sep_dn, sep_dn_len)) {
++			return -1;
++		}
++		ret = sep_dn_len;
++		if(!do_indent(io_ch, arg, indent)) {
++			return -1;
++		}
++		ret += indent;
++	}
++	return ret;
++}
++/* Bug 17749, end */
++
++/* Bug 15936, chenyl, 20070329 */
++/* copy from do_name_ex, call function do_print_ex_for_certm instead of do_print_ex */
++static int do_name_ex_for_certm(char_io *io_ch, void *arg, X509_NAME *n,
++                                int indent, unsigned long flags, char dn_sep, int dn_pos, void *poidname)
++{
++/* Bug 18421, chenyl, 20080121 */
++#define	RDNSEP_PREPOSE 1
++#define	RDNSEP_POSTPOSE	0	
++/* Bug 18421, end */
++	int i, prev = -1;
++	int cnt;
++	int fn_opt;
++	int outlen;
++	char *sep_dn, *sep_mv, *sep_eq;
++	int sep_dn_len, sep_mv_len, sep_eq_len;
++	rdn_position_t rdn[NID_MAX_COUNT];
++	position_t *pos = NULL, *pos_tmp = NULL;
++	int j;
++	int ret;
++	/* Bug 18421, chenyl, 20080121 */
++	char sep_tmp[2];
++	/* Bug 18421, end */
++	static int nid[NID_MAX_COUNT] = {NID_pkcs9_emailAddress, NID_userId, NID_title, 
++					 NID_commonName, NID_organizationalUnitName, 
++					 NID_organizationName, NID_localityName,
++	                                 NID_stateOrProvinceName, NID_countryName, 
++					 NID_domainComponent, NID_undef};
++	
++	if (indent < 0) {
++		indent = 0;
++	}
++	outlen = indent;
++	if (!do_indent(io_ch, arg, indent)) {
++		return -1;
++	}
++	switch (flags & XN_FLAG_SEP_MASK) {
++		case XN_FLAG_SEP_MULTILINE:
++		sep_dn = "\n";
++		sep_dn_len = 1;
++		sep_mv = " + ";
++		sep_mv_len = 3;
++		break;
++
++		case XN_FLAG_SEP_COMMA_PLUS:
++		sep_dn = ",";
++		sep_dn_len = 1;
++		sep_mv = "+";
++		sep_mv_len = 1;
++		indent = 0;
++		break;
++
++		case XN_FLAG_SEP_CPLUS_SPC:
++		sep_dn = ", ";
++		sep_dn_len = 2;
++		sep_mv = " + ";
++		sep_mv_len = 3;
++		indent = 0;
++		break;
++
++		case XN_FLAG_SEP_SPLUS_SPC:
++		sep_dn = "; ";
++		sep_dn_len = 2;
++		sep_mv = " + ";
++		sep_mv_len = 3;
++		indent = 0;
++		break;
++
++		default:
++		return -1;
++	}
++
++	if(flags & XN_FLAG_SPC_EQ) {
++		sep_eq = " = ";
++		sep_eq_len = 3;
++	} else {
++		sep_eq = "=";
++		sep_eq_len = 1;
++	}
++	/* Bug 18421, zhangjg, 20080121 */
++	sep_tmp[0] = dn_sep;
++	sep_tmp[1] = '\0';
++	sep_dn = sep_tmp;
++	sep_dn_len = 1;
++	
++	if (dn_pos == RDNSEP_PREPOSE) {
++		prev = 0; 
++		sep_mv = sep_dn;/*Bug 24526, chenhb, 20100303*/
++		sep_mv_len = sep_dn_len;
++	}
++	/* Bug 18421, end */
++	fn_opt = flags & XN_FLAG_FN_MASK;
++	for (i = 0; i < NID_MAX_COUNT; i++) {
++		TAILQ_INIT(&rdn[i]);
++	}
++	cnt = X509_NAME_entry_count(n);
++	pos = sort_rdn(rdn, n, cnt, flags); /*Bug 24526, chenhb, 20100303*/
++	if (pos == NULL) {
++		outlen = -1;
++		goto end;
++	}
++
++	/* Bug 17749, chenyl, 20071024 */
++	if(flags & X509_FLAG_COMMONNAME_ONLY) {
++		i =  COMMONNAME; 
++		if(TAILQ_EMPTY(&rdn[i])) {
++			goto end;
++		}
++		TAILQ_FOREACH(pos_tmp, &rdn[i], next) {
++			if(prev != -1) {
++				int rc = check_prev_for_X509_NAME_ENTRY_print(prev, pos_tmp, arg, sep_mv, 
++							sep_mv_len, sep_dn, sep_dn_len, io_ch, indent);
++				if(rc == -1) {
++					outlen = rc;
++					goto end;
++				} 
++				outlen += rc;
++			}
++			prev = pos_tmp->ent->set;
++			ret = X509_NAME_ENTRY_print(io_ch, arg, pos_tmp->ent, nid[i], 
++					    fn_opt, flags, sep_eq, sep_eq_len, NULL);
++			if(ret == -1) {
++				outlen = ret;
++				goto end;
++			} 
++			outlen += ret;
++		}
++		goto end;
++	}
++	/* Bug 17749, end */	
++	
++	/*Bug 24526, chenhb, 20100303*/	
++	if (flags & XN_FLAG_DN_ORI) {
++		if (TAILQ_EMPTY(&rdn[0])) {
++			outlen = -2;
++			goto end;
++		}
++		TAILQ_FOREACH(pos_tmp, &rdn[0], next) {
++				if(prev != -1) {
++					int rc = check_prev_for_X509_NAME_ENTRY_print(prev, pos_tmp, arg, 
++						sep_mv, sep_mv_len, sep_dn, sep_dn_len, io_ch, indent);
++					if(rc == -1) {
++						outlen = rc;
++						goto end;
++					}
++					outlen += rc;
++				}
++				prev = pos_tmp->ent->set;
++				ret = X509_NAME_ENTRY_print(io_ch, arg, pos_tmp->ent, pos_tmp->pos, 
++							    fn_opt, flags, sep_eq, sep_dn_len, poidname);		
++				if(ret == -1) {
++					outlen = ret;
++					goto end;
++				}
++				outlen += ret;
++		}
++		goto end;
++	}
++	/*Bug 24526, end*/
++	
++	for(i=0; i<NID_MAX_COUNT; i++) {
++		if (flags & XN_FLAG_DN_REV) {
++			j = NID_MAX_COUNT-i-1;	
++			if (TAILQ_EMPTY(&rdn[j])) {
++				continue;
++			}
++			
++			TAILQ_FOREACH_REVERSE(pos_tmp, &rdn[j], rdn_pos_tailq, next) {
++				if(prev != -1) {
++					int rc = check_prev_for_X509_NAME_ENTRY_print(prev, pos_tmp, arg, 
++						sep_mv, sep_mv_len, sep_dn, sep_dn_len, io_ch, indent);
++					if(rc == -1) {
++						outlen = rc;
++						goto end;
++					}
++					outlen += rc;
++				}
++				prev = pos_tmp->ent->set;
++				ret = X509_NAME_ENTRY_print(io_ch, arg, pos_tmp->ent, nid[j], 
++							    fn_opt, flags, sep_eq, sep_eq_len, poidname);
++				if(ret == -1) {
++					outlen = ret;
++					goto end;
++				}
++				outlen += ret;
++			}
++		} else {
++			if (TAILQ_EMPTY(&rdn[i])) {
++				continue;
++			}
++			TAILQ_FOREACH(pos_tmp, &rdn[i], next) {
++				if(prev != -1) {
++					int rc = check_prev_for_X509_NAME_ENTRY_print(prev, pos_tmp, arg, 
++						sep_mv, sep_mv_len, sep_dn, sep_dn_len, io_ch, indent);
++					if(rc == -1) {
++						outlen = rc;
++						goto end;
++					}
++					outlen += rc;
++				}
++				prev = pos_tmp->ent->set;
++				ret = X509_NAME_ENTRY_print(io_ch, arg, pos_tmp->ent, nid[i], 
++							    fn_opt, flags, sep_eq, sep_dn_len, poidname);		
++				if(ret == -1) {
++					outlen = ret;
++					goto end;
++				}
++				outlen += ret;
++			}
++		}
++	}
++
++end:
++	if (pos != NULL) {
++		free(pos);
++	}
++
++	return outlen;
++}
++/* Bug 15936, end */
++
+ /* Wrappers round the main functions */
+ 
+ int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
+@@ -565,6 +1252,20 @@ int X509_NAME_print_ex(BIO *out, const X509_NAME *nm, int indent,
+     return do_name_ex(send_bio_chars, out, nm, indent, flags);
+ }
+ 
++
++/* Bug 15936, chenyl, 20070329 */
++/* Note :copy from  X509_NAME_print_ex, call do_name_ex_for_certm instead of do_name_ex. 
++ *          X509_NAME_print_ex can't meet our requirement, so make some modification to it.
++ *          */
++int X509_NAME_print_ex_for_certm(BIO *out, X509_NAME *nm, int indent, unsigned long flags, 
++				char dn_sep, int dn_pos, void *poidname)
++{               
++        if(flags == XN_FLAG_COMPAT)
++                return X509_NAME_print(out, nm, indent);
++        return do_name_ex_for_certm(send_bio_chars, out, nm, indent, flags, dn_sep, dn_pos, poidname);
++}
++/* Bug 15936, end */
++
+ #ifndef OPENSSL_NO_STDIO
+ int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, int indent,
+                           unsigned long flags)
+diff --git a/crypto/asn1/tbl_standard.h b/crypto/asn1/tbl_standard.h
+index 777a734..2569d87 100644
+--- a/crypto/asn1/tbl_standard.h
++++ b/crypto/asn1/tbl_standard.h
+@@ -10,7 +10,7 @@
+ /* size limits: this stuff is taken straight from RFC3280 */
+ 
+ #define ub_name                         32768
+-#define ub_common_name                  64
++#define ub_common_name                  128
+ #define ub_locality_name                128
+ #define ub_state_name                   128
+ #define ub_organization_name            64
+diff --git a/crypto/rsa/rsa_locl.h b/crypto/rsa/rsa_locl.h
+index 2b94462..a7c0224 100644
+--- a/crypto/rsa/rsa_locl.h
++++ b/crypto/rsa/rsa_locl.h
+@@ -113,7 +113,7 @@ struct rsa_meth_st {
+ };
+ 
+ extern int int_rsa_verify(int dtype, const unsigned char *m,
+-                          unsigned int m_len, unsigned char *rm,
++                          unsigned int m_length, unsigned char *rm,
+                           size_t *prm_len, const unsigned char *sigbuf,
+                           size_t siglen, RSA *rsa);
+ /* Macros to test if a pkey or ctx is for a PSS key */
+diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
+index 975515d..dc5982a 100644
+--- a/crypto/stack/stack.c
++++ b/crypto/stack/stack.c
+@@ -22,7 +22,7 @@ static const int min_nodes = 4;
+ static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX
+                              ? (int)(SIZE_MAX / sizeof(void *))
+                              : INT_MAX;
+-
++# if 0
+ struct stack_st {
+     int num;
+     const void **data;
+@@ -30,6 +30,7 @@ struct stack_st {
+     int num_alloc;
+     OPENSSL_sk_compfunc comp;
+ };
++#endif
+ 
+ OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c)
+ {
+diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
+index 6be2c71..19facf7 100644
+--- a/crypto/x509/x509_vfy.c
++++ b/crypto/x509/x509_vfy.c
+@@ -304,6 +304,32 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
+     return ret;
+ }
+ 
++
++/* Bug 15969, chenyl, 20070429 */
++static int
++check_cert_signature(X509 *subject, X509 *issuer)
++{
++	EVP_PKEY        *pubkey = NULL;
++	int             ret;
++
++	if(subject == NULL || issuer == NULL) {
++		return 0;
++	}
++
++	pubkey = X509_get_pubkey(issuer);
++        if(pubkey == NULL){
++                return 0;
++        }
++	ret = X509_verify(subject, pubkey);
++	if(ret <= 0) {
++		EVP_PKEY_free(pubkey);
++		return 0;
++	}
++	EVP_PKEY_free(pubkey);
++	return 1;
++}
++/* Bug 15969, end */
++
+ /*
+  * Given a STACK_OF(X509) find the issuer of cert (if any)
+  */
+@@ -314,7 +340,10 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
+ 
+     for (i = 0; i < sk_X509_num(sk); i++) {
+         issuer = sk_X509_value(sk, i);
+-        if (ctx->check_issued(ctx, x, issuer)) {
++        /* Bug 15969, chenyl, 20070429
++  	 * add check_cert_signature
++  	*/
++        if (ctx->check_issued(ctx, x, issuer) && check_cert_signature(x, issuer)) {
+             rv = issuer;
+             if (x509_check_cert_time(ctx, rv, -1))
+                 break;
+diff --git a/include/openssl/stack.h b/include/openssl/stack.h
+index cfc0750..867158a 100644
+--- a/include/openssl/stack.h
++++ b/include/openssl/stack.h
+@@ -14,12 +14,21 @@
+ extern "C" {
+ #endif
+ 
++
+ typedef struct stack_st OPENSSL_STACK; /* Use STACK_OF(...) instead */
+ 
+ typedef int (*OPENSSL_sk_compfunc)(const void *, const void *);
+ typedef void (*OPENSSL_sk_freefunc)(void *);
+ typedef void *(*OPENSSL_sk_copyfunc)(const void *);
+ 
++struct stack_st {
++    int num;
++    const void **data;
++    int sorted;
++    int num_alloc;
++    OPENSSL_sk_compfunc comp;
++};
++
+ int OPENSSL_sk_num(const OPENSSL_STACK *);
+ void *OPENSSL_sk_value(const OPENSSL_STACK *, int);
+ 
+diff --git a/include/openssl/x509.h b/include/openssl/x509.h
+index 39ca0ba..9eeb284 100644
+--- a/include/openssl/x509.h
++++ b/include/openssl/x509.h
+@@ -160,6 +160,7 @@ DEFINE_STACK_OF(X509_TRUST)
+ # define X509_FLAG_NO_AUX                (1L << 10)
+ # define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
+ # define X509_FLAG_NO_IDS                (1L << 12)
++#define	X509_FLAG_COMMONNAME_ONLY        (1L << 13)
+ 
+ /* Flags specific to X509_NAME_print_ex() */
+ 
+@@ -196,6 +197,11 @@ DEFINE_STACK_OF(X509_TRUST)
+ # define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
+                                            * characters */
+ 
++/*Bug 24526, chenhb, 20100303*/
++#define XN_FLAG_DN_POS		(1 << 26)	/* Positive DN order */
++#define XN_FLAG_DN_ORI		(1 << 27)	/* Original DN order */
++/*Bug 24526, end*/
++
+ /* Complete set of RFC2253 flags */
+ 
+ # define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+@@ -778,6 +784,10 @@ int X509_aux_print(BIO *out, X509 *x, int indent);
+ # ifndef OPENSSL_NO_STDIO
+ int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
+                      unsigned long cflag);
++/* Bug 15936, chenyl, 20070329 */
++int X509_NAME_print_ex_for_certm(BIO *out, X509_NAME *nm, int indent, unsigned long flags, 
++				 char dn_sep, int dn_pos, void *poidname);
++/* Bug 15936, end */
+ int X509_print_fp(FILE *bp, X509 *x);
+ int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
+ int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
+diff --git a/util/libcrypto.num b/util/libcrypto.num
+index bf8b803..27d428b 100644
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -4582,3 +4582,4 @@ OPENSSL_INIT_set_config_file_flags      4535	1_1_1b	EXIST::FUNCTION:STDIO
+ EVP_PKEY_get0_engine                    4536	1_1_1c	EXIST::FUNCTION:ENGINE
+ X509_get0_authority_serial              4537	1_1_1d	EXIST::FUNCTION:
+ X509_get0_authority_issuer              4538	1_1_1d	EXIST::FUNCTION:
++X509_NAME_print_ex_for_certm            4539    1_1_1d  EXIST::FUNCTION:
+diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
+index 6693f27..79e278c 100644
+--- a/crypto/evp/digest.c
++++ b/crypto/evp/digest.c
+@@ -59,6 +59,7 @@ void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+ 
+ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
+ {
++    OPENSSL_cleanse(ctx, sizeof(*ctx));
+     EVP_MD_CTX_reset(ctx);
+     return EVP_DigestInit_ex(ctx, type, NULL);
+ }
+diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
+index 3cd7ca8..2273254 100644
+--- a/crypto/evp/p_lib.c
++++ b/crypto/evp/p_lib.c
+@@ -465,7 +465,7 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+ 
+ RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
+ {
+-    if (pkey->type != EVP_PKEY_RSA) {
++    if (pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_RSA_PSS) {
+         EVPerr(EVP_F_EVP_PKEY_GET0_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+         return NULL;
+     }
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4hc.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4hc.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-4hc.patch	(working copy)
@@ -0,0 +1,159 @@
+diff -urN openssl-1.1.1d-old/include/openssl/ssl.h openssl-1.1.1d/include/openssl/ssl.h
+--- openssl-1.1.1d-old/include/openssl/ssl.h	2020-05-27 04:18:27.249454759 -0400
++++ openssl-1.1.1d/include/openssl/ssl.h	2020-05-29 05:58:56.994866125 -0400
+@@ -1305,6 +1305,7 @@
+ # define SSL_CTRL_GET_MAX_PROTO_VERSION          131
+ # define SSL_CTRL_GET_SIGNATURE_NID              132
+ # define SSL_CTRL_GET_TMP_KEY                    133
++# define SSL_CTRL_SET_USTACK_PROTO_VERSION       134
+ # define SSL_CERT_SET_FIRST                      1
+ # define SSL_CERT_SET_NEXT                       2
+ # define SSL_CERT_SET_SERVER                     3
+@@ -1441,6 +1442,8 @@
+         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MIN_PROTO_VERSION, version, NULL)
+ # define SSL_CTX_set_max_proto_version(ctx, version) \
+         SSL_CTX_ctrl(ctx, SSL_CTRL_SET_MAX_PROTO_VERSION, version, NULL)
++# define SSL_CTX_set_ustack_proto_version(ctx, version) \
++        SSL_CTX_ctrl(ctx, SSL_CTRL_SET_USTACK_PROTO_VERSION, version, NULL)
+ # define SSL_CTX_get_min_proto_version(ctx) \
+         SSL_CTX_ctrl(ctx, SSL_CTRL_GET_MIN_PROTO_VERSION, 0, NULL)
+ # define SSL_CTX_get_max_proto_version(ctx) \
+@@ -1846,6 +1849,7 @@
+ long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
+ long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+ 
++
+ # define SSL_EARLY_DATA_NOT_SENT    0
+ # define SSL_EARLY_DATA_REJECTED    1
+ # define SSL_EARLY_DATA_ACCEPTED    2
+diff -urN openssl-1.1.1d-old/ssl/ssl_lib.c openssl-1.1.1d/ssl/ssl_lib.c
+--- openssl-1.1.1d-old/ssl/ssl_lib.c	2020-05-27 04:18:27.259454758 -0400
++++ openssl-1.1.1d/ssl/ssl_lib.c	2020-05-29 06:10:10.451818717 -0400
+@@ -706,6 +706,7 @@
+     s->dane.flags = ctx->dane.flags;
+     s->min_proto_version = ctx->min_proto_version;
+     s->max_proto_version = ctx->max_proto_version;
++    s->ustack_version = ctx->ustack_version;
+     s->mode = ctx->mode;
+     s->max_cert_list = ctx->max_cert_list;
+     s->max_early_data = ctx->max_early_data;
+@@ -2166,6 +2167,7 @@
+     return (s->renegotiate != 0);
+ }
+ 
++
+ long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
+ {
+     long l;
+@@ -2385,6 +2387,8 @@
+                                         &ctx->min_proto_version);
+     case SSL_CTRL_GET_MIN_PROTO_VERSION:
+         return ctx->min_proto_version;
++    case SSL_CTRL_SET_USTACK_PROTO_VERSION:
++	return ssl_set_ustack_support_version(larg, &ctx->ustack_version);
+     case SSL_CTRL_SET_MAX_PROTO_VERSION:
+         return ssl_check_allowed_versions(ctx->min_proto_version, larg)
+                && ssl_set_version_bound(ctx->method->version, (int)larg,
+@@ -2932,6 +2936,7 @@
+     ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
+     /* We take the system default. */
+     ret->session_timeout = meth->get_timeout();
++    ret->ustack_version = 0;
+     ret->references = 1;
+     ret->lock = CRYPTO_THREAD_lock_new();
+     if (ret->lock == NULL) {
+diff -urN openssl-1.1.1d-old/ssl/ssl_locl.h openssl-1.1.1d/ssl/ssl_locl.h
+--- openssl-1.1.1d-old/ssl/ssl_locl.h	2020-05-27 04:18:27.259454758 -0400
++++ openssl-1.1.1d/ssl/ssl_locl.h	2020-05-29 06:10:30.825817283 -0400
+@@ -861,6 +861,7 @@
+     uint32_t mode;
+     int min_proto_version;
+     int max_proto_version;
++    int ustack_version;
+     size_t max_cert_list;
+ 
+     struct cert_st /* CERT */ *cert;
+@@ -1241,6 +1242,7 @@
+     uint32_t mode;
+     int min_proto_version;
+     int max_proto_version;
++    int ustack_version;
+     size_t max_cert_list;
+     int first_packet;
+     /*
+@@ -2398,6 +2400,10 @@
+                                      DOWNGRADE *dgrd);
+ __owur int ssl_choose_client_version(SSL *s, int version,
+                                      RAW_EXTENSION *extensions);
++
++__owur int ssl_check_ustack_support_version(int current_version, int ustack_version);
++__owur int ssl_set_ustack_support_version(int ustack_version, int *ctx_ustack_version);
++
+ __owur int ssl_get_min_max_version(const SSL *s, int *min_version,
+                                    int *max_version, int *real_max);
+ 
+diff -urN openssl-1.1.1d-old/ssl/statem/statem_lib.c openssl-1.1.1d/ssl/statem/statem_lib.c
+--- openssl-1.1.1d-old/ssl/statem/statem_lib.c	2020-05-27 04:18:27.262454758 -0400
++++ openssl-1.1.1d/ssl/statem/statem_lib.c	2020-05-29 06:10:54.889815589 -0400
+@@ -1853,6 +1853,42 @@
+     return disabled ? SSL_R_UNSUPPORTED_PROTOCOL : SSL_R_VERSION_TOO_LOW;
+ }
+ 
++#define USTACK_SSLv30 0x01;
++#define USTACK_TLSv10 0x02;
++#define USTACK_TLSv11 0x04;
++#define USTACK_TLSv12 0x08;
++#define USTACK_TLSv13 0x10;
++
++int ssl_check_ustack_support_version(int current_version, int ustack_version) {
++	if (ustack_version != 0) {
++		switch (current_version) {
++			case SSL3_VERSION:
++				return ustack_version & USTACK_SSLv30;
++			case TLS1_VERSION:
++				return ustack_version & USTACK_TLSv10;
++			case TLS1_1_VERSION:
++				return ustack_version & USTACK_TLSv11;
++			case TLS1_2_VERSION:
++				return ustack_version & USTACK_TLSv12;
++			case TLS1_3_VERSION:
++				return ustack_version & USTACK_TLSv13;
++		}
++	}
++
++	return 1;
++}
++
++/*
++ * ssl_set_ustack_support_version
++ * we add this to change ustack_version, inorder to avoid hole in min_version & max_version
++ * * Returns 1 on success, 0 on failure.
++ */
++int ssl_set_ustack_support_version(int ustack_version, int *ctx_ustack_version)
++{
++    *ctx_ustack_version = ustack_version; 
++    return 1;
++}
++
+ /*
+  * ssl_choose_client_version - Choose client (D)TLS version.  Called when the
+  * server HELLO is received to select the final client protocol version and
+@@ -1906,7 +1942,8 @@
+          * versions they don't want.  If not, then easy to fix, just return
+          * ssl_method_error(s, s->method)
+          */
+-        return 1;
++	
++        return ssl_check_ustack_support_version(s->version, s->ustack_version);
+     case TLS_ANY_VERSION:
+         table = tls_version_table;
+         break;
+@@ -1971,7 +2008,7 @@
+             continue;
+ 
+         s->method = vent->cmeth();
+-        return 1;
++        return ssl_check_ustack_support_version(s->version, s->ustack_version);
+     }
+ 
+     s->version = origv;
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-CVE-2022-0778.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-CVE-2022-0778.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-CVE-2022-0778.patch	(working copy)
@@ -0,0 +1,49 @@
+diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
+index 1723d5ded5a87a0d0b665df15678b6013bcce2f7..53b0f559855c10fe5a97ea90f137afe7671ee08f 100644 (file)
+--- a/crypto/bn/bn_sqrt.c
++++ b/crypto/bn/bn_sqrt.c
+@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+ /*
+  * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
+  * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
+- * Theory", algorithm 1.5.1). 'p' must be prime!
++ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or
++ * an incorrect "result" will be returned.
+  */
+ {
+     BIGNUM *ret = in;
+@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
+             goto vrfy;
+         }
+ 
+-        /* find smallest  i  such that  b^(2^i) = 1 */
+-        i = 1;
+-        if (!BN_mod_sqr(t, b, p, ctx))
+-            goto end;
+-        while (!BN_is_one(t)) {
+-            i++;
+-            if (i == e) {
+-                BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+-                goto end;
++        /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */
++        for (i = 1; i < e; i++) {
++            if (i == 1) {
++                if (!BN_mod_sqr(t, b, p, ctx))
++                    goto end;
++
++            } else {
++                if (!BN_mod_mul(t, t, t, p, ctx))
++                    goto end;
+             }
+-            if (!BN_mod_mul(t, t, t, p, ctx))
+-                goto end;
++            if (BN_is_one(t))
++                break;
++        }
++        /* If not found, a is not a square or p is not prime. */
++        if (i >= e) {
++            BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
++            goto end;
+         }
+ 
+         /* t := y^2^(e - i - 1) */
\ No newline at end of file
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug100709.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug100709.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug100709.patch	(working copy)
@@ -0,0 +1,79 @@
+diff -urN openssl-1.1.1d/crypto/x509v3/v3_genn.c openssl-1.1.1d-new/crypto/x509v3/v3_genn.c
+--- openssl-1.1.1d/crypto/x509v3/v3_genn.c	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d-new/crypto/x509v3/v3_genn.c	2020-12-10 14:10:00.347507387 +0800
+@@ -57,6 +57,37 @@
+                                     (char *)a);
+ }
+ 
++static int edipartyname_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
++{
++    int res;
++
++    if (a == NULL || b == NULL) {
++        /*
++         * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
++         * anyway. OTHERNAME_cmp treats NULL != NULL so we do the same here
++         */
++        return -1;
++    }
++    if (a->nameAssigner == NULL && b->nameAssigner != NULL)
++        return -1;
++    if (a->nameAssigner != NULL && b->nameAssigner == NULL)
++        return 1;
++    /* If we get here then both have nameAssigner set, or both unset */
++    if (a->nameAssigner != NULL) {
++        res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
++        if (res != 0)
++            return res;
++    }
++    /*
++     * partyName is required, so these should never be NULL. We treat it in
++     * the same way as the a == NULL || b == NULL case above
++     */
++    if (a->partyName == NULL || b->partyName == NULL)
++        return -1;
++
++    return ASN1_STRING_cmp(a->partyName, b->partyName);
++}
++
+ /* Returns 0 if they are equal, != 0 otherwise. */
+ int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
+ {
+@@ -66,8 +97,11 @@
+         return -1;
+     switch (a->type) {
+     case GEN_X400:
++        result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
++        break;
++
+     case GEN_EDIPARTY:
+-        result = ASN1_TYPE_cmp(a->d.other, b->d.other);
++        result = edipartyname_cmp(a->d.ediPartyName, b->d.ediPartyName);
+         break;
+ 
+     case GEN_OTHERNAME:
+@@ -114,8 +148,11 @@
+ {
+     switch (type) {
+     case GEN_X400:
++        a->d.x400Address = value;
++        break;
++
+     case GEN_EDIPARTY:
+-        a->d.other = value;
++        a->d.ediPartyName = value;
+         break;
+ 
+     case GEN_OTHERNAME:
+@@ -149,8 +186,10 @@
+         *ptype = a->type;
+     switch (a->type) {
+     case GEN_X400:
++        return a->d.x400Address;
++
+     case GEN_EDIPARTY:
+-        return a->d.other;
++        return a->d.ediPartyName;
+ 
+     case GEN_OTHERNAME:
+         return a->d.otherName;
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug102140.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug102140.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug102140.patch	(working copy)
@@ -0,0 +1,362 @@
+diff -urN openssl-1.1.1d/crypto/ec/asm/ecp_nistz256-x86_64.pl openssl-1.1.1d-new/crypto/ec/asm/ecp_nistz256-x86_64.pl
+--- openssl-1.1.1d/crypto/ec/asm/ecp_nistz256-x86_64.pl	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d-new/crypto/ec/asm/ecp_nistz256-x86_64.pl	2021-01-29 16:10:45.184893060 +0800
+@@ -1599,7 +1599,6 @@
+ .type	ecp_nistz256_mul_mont,\@function,3
+ .align	32
+ ecp_nistz256_mul_mont:
+-.cfi_startproc
+ ___
+ $code.=<<___	if ($addx);
+ 	mov	\$0x80100, %ecx
+@@ -1608,18 +1607,11 @@
+ $code.=<<___;
+ .Lmul_mont:
+ 	push	%rbp
+-.cfi_push	%rbp
+ 	push	%rbx
+-.cfi_push	%rbx
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+ 	push	%r14
+-.cfi_push	%r14
+ 	push	%r15
+-.cfi_push	%r15
+-.Lmul_body:
+ ___
+ $code.=<<___	if ($addx);
+ 	cmp	\$0x80100, %ecx
+@@ -1652,23 +1644,13 @@
+ ___
+ $code.=<<___;
+ .Lmul_mont_done:
+-	mov	0(%rsp),%r15
+-.cfi_restore	%r15
+-	mov	8(%rsp),%r14
+-.cfi_restore	%r14
+-	mov	16(%rsp),%r13
+-.cfi_restore	%r13
+-	mov	24(%rsp),%r12
+-.cfi_restore	%r12
+-	mov	32(%rsp),%rbx
+-.cfi_restore	%rbx
+-	mov	40(%rsp),%rbp
+-.cfi_restore	%rbp
+-	lea	48(%rsp),%rsp
+-.cfi_adjust_cfa_offset	-48
+-.Lmul_epilogue:
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
++	pop	%rbx
++	pop	%rbp
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_mul_mont,.-ecp_nistz256_mul_mont
+ 
+ .type	__ecp_nistz256_mul_montq,\@abi-omnipotent
+@@ -1900,7 +1882,6 @@
+ .type	ecp_nistz256_sqr_mont,\@function,2
+ .align	32
+ ecp_nistz256_sqr_mont:
+-.cfi_startproc
+ ___
+ $code.=<<___	if ($addx);
+ 	mov	\$0x80100, %ecx
+@@ -1908,18 +1889,11 @@
+ ___
+ $code.=<<___;
+ 	push	%rbp
+-.cfi_push	%rbp
+ 	push	%rbx
+-.cfi_push	%rbx
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+ 	push	%r14
+-.cfi_push	%r14
+ 	push	%r15
+-.cfi_push	%r15
+-.Lsqr_body:
+ ___
+ $code.=<<___	if ($addx);
+ 	cmp	\$0x80100, %ecx
+@@ -1948,23 +1922,13 @@
+ ___
+ $code.=<<___;
+ .Lsqr_mont_done:
+-	mov	0(%rsp),%r15
+-.cfi_restore	%r15
+-	mov	8(%rsp),%r14
+-.cfi_restore	%r14
+-	mov	16(%rsp),%r13
+-.cfi_restore	%r13
+-	mov	24(%rsp),%r12
+-.cfi_restore	%r12
+-	mov	32(%rsp),%rbx
+-.cfi_restore	%rbx
+-	mov	40(%rsp),%rbp
+-.cfi_restore	%rbp
+-	lea	48(%rsp),%rsp
+-.cfi_adjust_cfa_offset	-48
+-.Lsqr_epilogue:
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
++	pop	%rbx
++	pop	%rbp
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_sqr_mont,.-ecp_nistz256_sqr_mont
+ 
+ .type	__ecp_nistz256_sqr_montq,\@abi-omnipotent
+@@ -2451,12 +2415,8 @@
+ .type	ecp_nistz256_from_mont,\@function,2
+ .align	32
+ ecp_nistz256_from_mont:
+-.cfi_startproc
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+-.Lfrom_body:
+ 
+ 	mov	8*0($in_ptr), %rax
+ 	mov	.Lpoly+8*3(%rip), $t2
+@@ -2537,15 +2497,9 @@
+ 	mov	$acc2, 8*2($r_ptr)
+ 	mov	$acc3, 8*3($r_ptr)
+ 
+-	mov	0(%rsp),%r13
+-.cfi_restore	%r13
+-	mov	8(%rsp),%r12
+-.cfi_restore	%r12
+-	lea	16(%rsp),%rsp
+-.cfi_adjust_cfa_offset	-16
+-.Lfrom_epilogue:
++	pop	%r13
++	pop	%r12
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_from_mont,.-ecp_nistz256_from_mont
+ ___
+ }
+@@ -3223,7 +3177,6 @@
+ .type	ecp_nistz256_point_double,\@function,2
+ .align	32
+ ecp_nistz256_point_double:
+-.cfi_startproc
+ ___
+ $code.=<<___	if ($addx);
+ 	mov	\$0x80100, %ecx
+@@ -3240,26 +3193,17 @@
+ .type	ecp_nistz256_point_doublex,\@function,2
+ .align	32
+ ecp_nistz256_point_doublex:
+-.cfi_startproc
+ .Lpoint_doublex:
+ ___
+     }
+ $code.=<<___;
+ 	push	%rbp
+-.cfi_push	%rbp
+ 	push	%rbx
+-.cfi_push	%rbx
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+ 	push	%r14
+-.cfi_push	%r14
+ 	push	%r15
+-.cfi_push	%r15
+ 	sub	\$32*5+8, %rsp
+-.cfi_adjust_cfa_offset	32*5+8
+-.Lpoint_double${x}_body:
+ 
+ .Lpoint_double_shortcut$x:
+ 	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$a_ptr.x
+@@ -3430,25 +3374,14 @@
+ 	movq	%xmm1, $r_ptr
+ 	call	__ecp_nistz256_sub_from$x	# p256_sub(res_y, S, res_y);
+ 
+-	lea	32*5+56(%rsp), %rsi
+-.cfi_def_cfa	%rsi,8
+-	mov	-48(%rsi),%r15
+-.cfi_restore	%r15
+-	mov	-40(%rsi),%r14
+-.cfi_restore	%r14
+-	mov	-32(%rsi),%r13
+-.cfi_restore	%r13
+-	mov	-24(%rsi),%r12
+-.cfi_restore	%r12
+-	mov	-16(%rsi),%rbx
+-.cfi_restore	%rbx
+-	mov	-8(%rsi),%rbp
+-.cfi_restore	%rbp
+-	lea	(%rsi),%rsp
+-.cfi_def_cfa_register	%rsp
+-.Lpoint_double${x}_epilogue:
++	add	\$32*5+8, %rsp
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
++	pop	%rbx
++	pop	%rbp
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_point_double$sfx,.-ecp_nistz256_point_double$sfx
+ ___
+ }
+@@ -3474,7 +3407,6 @@
+ .type	ecp_nistz256_point_add,\@function,3
+ .align	32
+ ecp_nistz256_point_add:
+-.cfi_startproc
+ ___
+ $code.=<<___	if ($addx);
+ 	mov	\$0x80100, %ecx
+@@ -3491,26 +3423,17 @@
+ .type	ecp_nistz256_point_addx,\@function,3
+ .align	32
+ ecp_nistz256_point_addx:
+-.cfi_startproc
+ .Lpoint_addx:
+ ___
+     }
+ $code.=<<___;
+ 	push	%rbp
+-.cfi_push	%rbp
+ 	push	%rbx
+-.cfi_push	%rbx
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+ 	push	%r14
+-.cfi_push	%r14
+ 	push	%r15
+-.cfi_push	%r15
+ 	sub	\$32*18+8, %rsp
+-.cfi_adjust_cfa_offset	32*18+8
+-.Lpoint_add${x}_body:
+ 
+ 	movdqu	0x00($a_ptr), %xmm0		# copy	*(P256_POINT *)$a_ptr
+ 	movdqu	0x10($a_ptr), %xmm1
+@@ -3644,9 +3567,7 @@
+ 	movq	%xmm1, $a_ptr			# restore $a_ptr
+ 	movq	%xmm0, $r_ptr			# restore $r_ptr
+ 	add	\$`32*(18-5)`, %rsp		# difference in frame sizes
+-.cfi_adjust_cfa_offset	`-32*(18-5)`
+ 	jmp	.Lpoint_double_shortcut$x
+-.cfi_adjust_cfa_offset	`32*(18-5)`
+ 
+ .align	32
+ .Ladd_proceed$x:
+@@ -3821,25 +3742,14 @@
+ 	movdqu	%xmm3, 0x30($r_ptr)
+ 
+ .Ladd_done$x:
+-	lea	32*18+56(%rsp), %rsi
+-.cfi_def_cfa	%rsi,8
+-	mov	-48(%rsi),%r15
+-.cfi_restore	%r15
+-	mov	-40(%rsi),%r14
+-.cfi_restore	%r14
+-	mov	-32(%rsi),%r13
+-.cfi_restore	%r13
+-	mov	-24(%rsi),%r12
+-.cfi_restore	%r12
+-	mov	-16(%rsi),%rbx
+-.cfi_restore	%rbx
+-	mov	-8(%rsi),%rbp
+-.cfi_restore	%rbp
+-	lea	(%rsi),%rsp
+-.cfi_def_cfa_register	%rsp
+-.Lpoint_add${x}_epilogue:
++	add	\$32*18+8, %rsp
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
++	pop	%rbx
++	pop	%rbp
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_point_add$sfx,.-ecp_nistz256_point_add$sfx
+ ___
+ }
+@@ -3864,7 +3774,6 @@
+ .type	ecp_nistz256_point_add_affine,\@function,3
+ .align	32
+ ecp_nistz256_point_add_affine:
+-.cfi_startproc
+ ___
+ $code.=<<___	if ($addx);
+ 	mov	\$0x80100, %ecx
+@@ -3881,26 +3790,17 @@
+ .type	ecp_nistz256_point_add_affinex,\@function,3
+ .align	32
+ ecp_nistz256_point_add_affinex:
+-.cfi_startproc
+ .Lpoint_add_affinex:
+ ___
+     }
+ $code.=<<___;
+ 	push	%rbp
+-.cfi_push	%rbp
+ 	push	%rbx
+-.cfi_push	%rbx
+ 	push	%r12
+-.cfi_push	%r12
+ 	push	%r13
+-.cfi_push	%r13
+ 	push	%r14
+-.cfi_push	%r14
+ 	push	%r15
+-.cfi_push	%r15
+ 	sub	\$32*15+8, %rsp
+-.cfi_adjust_cfa_offset	32*15+8
+-.Ladd_affine${x}_body:
+ 
+ 	movdqu	0x00($a_ptr), %xmm0	# copy	*(P256_POINT *)$a_ptr
+ 	mov	$b_org, $b_ptr		# reassign
+@@ -4145,25 +4045,14 @@
+ 	movdqu	%xmm2, 0x20($r_ptr)
+ 	movdqu	%xmm3, 0x30($r_ptr)
+ 
+-	lea	32*15+56(%rsp), %rsi
+-.cfi_def_cfa	%rsi,8
+-	mov	-48(%rsi),%r15
+-.cfi_restore	%r15
+-	mov	-40(%rsi),%r14
+-.cfi_restore	%r14
+-	mov	-32(%rsi),%r13
+-.cfi_restore	%r13
+-	mov	-24(%rsi),%r12
+-.cfi_restore	%r12
+-	mov	-16(%rsi),%rbx
+-.cfi_restore	%rbx
+-	mov	-8(%rsi),%rbp
+-.cfi_restore	%rbp
+-	lea	(%rsi),%rsp
+-.cfi_def_cfa_register	%rsp
+-.Ladd_affine${x}_epilogue:
++	add	\$32*15+8, %rsp
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
++	pop	%rbx
++	pop	%rbp
+ 	ret
+-.cfi_endproc
+ .size	ecp_nistz256_point_add_affine$sfx,.-ecp_nistz256_point_add_affine$sfx
+ ___
+ }
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug105409.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug105409.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug105409.patch	(working copy)
@@ -0,0 +1,91 @@
+diff -urNa -r openssl-1.1.1d/crypto/rand/rand_lib.c openssl-1.1.1d.random/crypto/rand/rand_lib.c
+--- openssl-1.1.1d/crypto/rand/rand_lib.c	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d.random/crypto/rand/rand_lib.c	2021-05-20 22:24:02.363290196 +0800
+@@ -7,6 +7,8 @@
+  * https://www.openssl.org/source/license.html
+  */
+ 
++#include <stdlib.h>
++#include <time.h>
+ #include <stdio.h>
+ #include <time.h>
+ #include "internal/cryptlib.h"
+@@ -908,6 +910,46 @@
+         meth->add(buf, num, randomness);
+ }
+ 
++static unsigned int getstimeval(){
++	unsigned int us;
++	struct timeval tv;
++	gettimeofday(&tv, NULL);
++	us = (int)tv.tv_usec;
++	return us;
++}
++
++static void array_gen_random(unsigned char *array, int array_len_bytes)
++{
++	uint32_t	randval;   /* 4-byte random number obtained using function call. */
++	uint32_t	*array_32; /* Viewing the buffer to contain 32-bit values. */
++	uint32_t	index;     /* Loop index. */
++
++	array_32 = (uint32_t *) array;
++
++	/* Use the ARC-4 stream cipher to generate the random numbers into the array
++	 * as offered by the C function "arc4random". */
++	srand(getstimeval());
++	for (index = 0; index < array_len_bytes/sizeof(uint32_t); index++) {
++	/* Fill the random number just obtained into 4 bytes in the array. */
++		randval= random();
++
++		array_32[index] = randval;
++	}
++
++	if (array_len_bytes % sizeof(uint32_t)) {
++	/* The remaining (array_len_bytes % sizeof(uint32_t)) bytes of "array" are
++	* still unfilled. Process these remaining bytes. */
++                randval= random();
++		index = array_len_bytes/sizeof(uint32_t) * sizeof(uint32_t);
++		
++		while (index < array_len_bytes) {
++			array[index] = (uint8_t) (randval & ((1 << (8*sizeof(uint8_t))) - 1));
++			randval >>= (8 * sizeof(uint8_t));
++			index++;
++		}
++	}
++}
++
+ /*
+  * This function is not part of RAND_METHOD, so if we're not using
+  * the default method, then just call RAND_bytes().  Otherwise make
+@@ -915,6 +957,7 @@
+  */
+ int RAND_priv_bytes(unsigned char *buf, int num)
+ {
++#if 0
+     const RAND_METHOD *meth = RAND_get_rand_method();
+     RAND_DRBG *drbg;
+     int ret;
+@@ -928,16 +971,23 @@
+ 
+     ret = RAND_DRBG_bytes(drbg, buf, num);
+     return ret;
++#endif
++	array_gen_random(buf, num);
++	return 1;
+ }
+ 
+ int RAND_bytes(unsigned char *buf, int num)
+ {
++#if 0
+     const RAND_METHOD *meth = RAND_get_rand_method();
+ 
+     if (meth->bytes != NULL)
+         return meth->bytes(buf, num);
+     RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
+     return -1;
++#endif
++	array_gen_random(buf, num);
++	return 1;
+ }
+ 
+ #if OPENSSL_API_COMPAT < 0x10100000L
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug109332.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug109332.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug109332.patch	(working copy)
@@ -0,0 +1,17 @@
+--- branches/rel_apv_10_4_1_xinchuang/usr/click/lib/libopenssl-1.1.1/openssl-1.1.1d-bug109332.patch	                        (rev 0)
++++ branches/rel_apv_10_4_1_xinchuang/usr/click/lib/libopenssl-1.1.1/openssl-1.1.1d-bug109332.patch	2021-08-30 08:13:46 UTC (rev 21257)
+@@ -0,0 +1,14 @@
++--- openssl-1.1.1d/crypto/ec/ec_asn1.c	2019-09-10 21:13:07.000000000 +0800
+++++ openssl-1.1.1d.new/crypto/ec/ec_asn1.c	2021-08-30 12:34:22.302170535 +0800
++@@ -744,7 +744,10 @@
++         ret->seed_len = params->curve->seed->length;
++     }
++
++-    if (!params->order || !params->base || !params->base->data) {
+++    if (params->order == NULL
+++            || params->base == NULL
+++            || params->base->data == NULL
+++            || params->base->length == 0) {
++         ECerr(EC_F_EC_GROUP_NEW_FROM_ECPARAMETERS, EC_R_ASN1_ERROR);
++         goto err;
++     }
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93451.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93451.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93451.patch	(working copy)
@@ -0,0 +1,267 @@
+diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
+index f7c575d..dde05b7 100644
+--- a/crypto/rsa/rsa_pss.c
++++ b/crypto/rsa/rsa_pss.c
+@@ -135,6 +135,112 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+ 
+ }
+ 
++int Array_RSA_verify_PKCS1_PSS_mgf1(int keylen_bit, const unsigned char *mHash,
++                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
++                              const unsigned char *EM, int sLen)
++{
++    int i;
++    int ret = 0;
++    int hLen, maskedDBLen, MSBits, emLen;
++    const unsigned char *H;
++    unsigned char *DB = NULL;
++    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
++    unsigned char H_[EVP_MAX_MD_SIZE];
++
++    if (ctx == NULL)
++        goto err;
++
++    if (mgf1Hash == NULL)
++        mgf1Hash = Hash;
++
++    hLen = EVP_MD_size(Hash);
++    if (hLen < 0)
++        goto err;
++    /*-
++     * Negative sLen has special meanings:
++     *      -1      sLen == hLen
++     *      -2      salt length is autorecovered from signature
++     *      -3      salt length is maximized
++     *      -N      reserved
++     */
++    if (sLen == RSA_PSS_SALTLEN_DIGEST) {
++        sLen = hLen;
++    } else if (sLen < RSA_PSS_SALTLEN_MAX) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
++        goto err;
++    }
++
++    MSBits = (keylen_bit - 1) & 0x7;
++    emLen = (keylen_bit+7)/8;
++    if (EM[0] & (0xFF << MSBits)) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
++        goto err;
++    }
++    if (MSBits == 0) {
++        EM++;
++        emLen--;
++    }
++    if (emLen < hLen + 2) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
++        goto err;
++    }
++    if (sLen == RSA_PSS_SALTLEN_MAX) {
++        sLen = emLen - hLen - 2;
++    } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
++        goto err;
++    }
++    if (EM[emLen - 1] != 0xbc) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
++        goto err;
++    }
++    maskedDBLen = emLen - hLen - 1;
++    H = EM + maskedDBLen;
++    DB = OPENSSL_malloc(maskedDBLen);
++    if (DB == NULL) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
++        goto err;
++    }
++    if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
++        goto err;
++    for (i = 0; i < maskedDBLen; i++)
++        DB[i] ^= EM[i];
++    if (MSBits)
++        DB[0] &= 0xFF >> (8 - MSBits);
++    for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
++    if (DB[i++] != 0x1) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
++        goto err;
++    }
++    if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
++        goto err;
++    }
++    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
++        || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes))
++        || !EVP_DigestUpdate(ctx, mHash, hLen))
++        goto err;
++    if (maskedDBLen - i) {
++        if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
++            goto err;
++    }
++    if (!EVP_DigestFinal_ex(ctx, H_, NULL))
++        goto err;
++    if (memcmp(H_, H, hLen)) {
++        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
++        ret = 0;
++    } else {
++        ret = 1;
++    }
++
++ err:
++    OPENSSL_free(DB);
++    EVP_MD_CTX_free(ctx);
++
++    return ret;
++
++}
++
+ int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+                               const unsigned char *mHash,
+                               const EVP_MD *Hash, int sLen)
+@@ -250,6 +356,114 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+ 
+ }
+ 
++int Array_RSA_padding_add_PKCS1_PSS_mgf1(int keylen_bit, unsigned char *EM,
++                                   const unsigned char *mHash,
++                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
++                                   int sLen)
++{
++    int i;
++    int ret = 0;
++    int hLen, maskedDBLen, MSBits, emLen;
++    unsigned char *H, *salt = NULL, *p;
++    EVP_MD_CTX *ctx = NULL;
++
++    if (mgf1Hash == NULL)
++        mgf1Hash = Hash;
++
++    hLen = EVP_MD_size(Hash);
++    if (hLen < 0)
++        goto err;
++    /*-
++     * Negative sLen has special meanings:
++     *      -1      sLen == hLen
++     *      -2      salt length is maximized
++     *      -3      same as above (on signing)
++     *      -N      reserved
++     */
++    if (sLen == RSA_PSS_SALTLEN_DIGEST) {
++        sLen = hLen;
++    } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) {
++        sLen = RSA_PSS_SALTLEN_MAX;
++    } else if (sLen < RSA_PSS_SALTLEN_MAX) {
++        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
++        goto err;
++    }
++
++    MSBits = (keylen_bit - 1) & 0x7;
++    emLen = (keylen_bit+7)/8;
++    if (MSBits == 0) {
++        *EM++ = 0;
++        emLen--;
++    }
++    if (emLen < hLen + 2) {
++        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
++               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
++        goto err;
++    }
++    if (sLen == RSA_PSS_SALTLEN_MAX) {
++        sLen = emLen - hLen - 2;
++    } else if (sLen > emLen - hLen - 2) {
++        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
++               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
++        goto err;
++    }
++    if (sLen > 0) {
++        salt = OPENSSL_malloc(sLen);
++        if (salt == NULL) {
++            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
++                   ERR_R_MALLOC_FAILURE);
++            goto err;
++        }
++        if (RAND_bytes(salt, sLen) <= 0)
++            goto err;
++    }
++    maskedDBLen = emLen - hLen - 1;
++    H = EM + maskedDBLen;
++    ctx = EVP_MD_CTX_new();
++    if (ctx == NULL)
++        goto err;
++    if (!EVP_DigestInit_ex(ctx, Hash, NULL)
++        || !EVP_DigestUpdate(ctx, zeroes, sizeof(zeroes))
++        || !EVP_DigestUpdate(ctx, mHash, hLen))
++        goto err;
++    if (sLen && !EVP_DigestUpdate(ctx, salt, sLen))
++        goto err;
++    if (!EVP_DigestFinal_ex(ctx, H, NULL))
++        goto err;
++
++    /* Generate dbMask in place then perform XOR on it */
++    if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash))
++        goto err;
++
++    p = EM;
++
++    /*
++     * Initial PS XORs with all zeroes which is a NOP so just update pointer.
++     * Note from a test above this value is guaranteed to be non-negative.
++     */
++    p += emLen - sLen - hLen - 2;
++    *p++ ^= 0x1;
++    if (sLen > 0) {
++        for (i = 0; i < sLen; i++)
++            *p++ ^= salt[i];
++    }
++    if (MSBits)
++        EM[0] &= 0xFF >> (8 - MSBits);
++
++    /* H is already in place so just set final 0xbc */
++
++    EM[emLen - 1] = 0xbc;
++
++    ret = 1;
++
++ err:
++    EVP_MD_CTX_free(ctx);
++    OPENSSL_clear_free(salt, (size_t)sLen); /* salt != NULL implies sLen > 0 */
++
++    return ret;
++
++}
++
+ #if defined(_MSC_VER)
+ # pragma optimize("",on)
+ #endif
+diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
+index cdce126..4b7139d 100644
+--- a/include/openssl/rsa.h
++++ b/include/openssl/rsa.h
+@@ -383,11 +383,20 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
+                               const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                               const unsigned char *EM, int sLen);
+ 
++int Array_RSA_verify_PKCS1_PSS_mgf1(int keylen_bit, const unsigned char *mHash,
++                              const EVP_MD *Hash, const EVP_MD *mgf1Hash,
++                              const unsigned char *EM, int sLen);
++
+ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
+                                    const unsigned char *mHash,
+                                    const EVP_MD *Hash, const EVP_MD *mgf1Hash,
+                                    int sLen);
+ 
++int Array_RSA_padding_add_PKCS1_PSS_mgf1(int keylen_bit, unsigned char *EM,
++                                   const unsigned char *mHash,
++                                   const EVP_MD *Hash, const EVP_MD *mgf1Hash,
++                                   int sLen);
++
+ #define RSA_get_ex_new_index(l, p, newf, dupf, freef) \
+     CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, l, p, newf, dupf, freef)
+ int RSA_set_ex_data(RSA *r, int idx, void *arg);
+diff --git a/util/libcrypto.num b/util/libcrypto.num
+index 14c1cef..1b3cff4 100644
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -4586,3 +4586,5 @@ X509_NAME_print_ex_for_certm            4539    1_1_1d  EXIST::FUNCTION:
+ array_sm2_decrypt                       4540    1_1_1d  EXIST::FUNCTION:SM2
+ sms4_set_key                            4541    1_1_1d  EXIST::FUNCTION:SM4
+ sms4_ecb_decrypt                        4542    1_1_1d  EXIST::FUNCTION:SM4
++Array_RSA_verify_PKCS1_PSS_mgf1         4543    1_1_1d  EXIST::FUNCTION:RSA
++Array_RSA_padding_add_PKCS1_PSS_mgf1    4544    1_1_1d  EXIST::FUNCTION:RSA
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93700.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93700.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug93700.patch	(working copy)
@@ -0,0 +1,56 @@
+diff -urN openssl-1.1.1d/crypto/sm2/sm2_sign.c openssl-1.1.1d-new/crypto/sm2/sm2_sign.c
+--- openssl-1.1.1d/crypto/sm2/sm2_sign.c	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d-new/crypto/sm2/sm2_sign.c	2020-11-06 11:36:51.017945210 +0800
+@@ -477,3 +477,18 @@
+     ECDSA_SIG_free(s);
+     return ret;
+ }
++
++int array_sm2_do_verify(const EC_KEY *key,
++                  const EVP_MD *digest,
++                  const ECDSA_SIG *sig,
++                  const uint8_t *id,
++                  const size_t id_len,
++                  const uint8_t *msg, size_t msg_len)
++{
++	return sm2_do_verify(key,
++                  digest,
++                  sig,
++                  id,
++                  id_len,
++                  msg, msg_len);
++}
+diff -urN openssl-1.1.1d/include/openssl/sm2_sm4_g.h openssl-1.1.1d-new/include/openssl/sm2_sm4_g.h
+--- openssl-1.1.1d/include/openssl/sm2_sm4_g.h	2020-11-06 13:58:19.029347701 +0800
++++ openssl-1.1.1d-new/include/openssl/sm2_sm4_g.h	2020-11-06 13:58:47.483345698 +0800
+@@ -12,6 +12,7 @@
+ 
+ #include <openssl/opensslconf.h>
+ #include <openssl/ossl_typ.h>
++#include <openssl/ec.h>
+ 
+ 
+ #include <stddef.h>
+@@ -37,6 +38,14 @@
+                 unsigned int *outputtext_len_bytes,
+                 const unsigned char *ciphertext,
+                 unsigned int ciphertext_len_bytes);
++
++int array_sm2_do_verify(const EC_KEY *key,
++		  const EVP_MD *digest,
++		  const ECDSA_SIG *sig,
++		  const uint8_t *id,
++		  const size_t id_len,
++		  const uint8_t *msg, size_t msg_len);
++
+ #endif
+ 
+ # ifdef  __cplusplus
+diff -urN openssl-1.1.1d/util/libcrypto.num openssl-1.1.1d-new/util/libcrypto.num
+--- openssl-1.1.1d/util/libcrypto.num	2020-11-06 13:58:19.033347700 +0800
++++ openssl-1.1.1d-new/util/libcrypto.num	2020-11-06 11:39:24.680934393 +0800
+@@ -4588,3 +4588,4 @@
+ sms4_ecb_decrypt                        4542    1_1_1d  EXIST::FUNCTION:SM4
+ Array_RSA_verify_PKCS1_PSS_mgf1         4543    1_1_1d  EXIST::FUNCTION:RSA
+ Array_RSA_padding_add_PKCS1_PSS_mgf1    4544    1_1_1d  EXIST::FUNCTION:RSA
++array_sm2_do_verify                     4545    1_1_1d  EXIST::FUNCTION:SM2
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94781.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94781.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94781.patch	(working copy)
@@ -0,0 +1,18 @@
+diff -urN openssl-1.1.1d-old/crypto/evp/c_allc.c openssl-1.1.1d/crypto/evp/c_allc.c
+--- openssl-1.1.1d-old/crypto/evp/c_allc.c	2020-05-27 04:18:27.108454769 -0400
++++ openssl-1.1.1d/crypto/evp/c_allc.c	2020-06-05 00:14:39.836745669 -0400
+@@ -87,6 +87,14 @@
+     EVP_add_cipher(EVP_sm4_ctr());
+     EVP_add_cipher_alias(SN_sm4_cbc, "SM4");
+     EVP_add_cipher_alias(SN_sm4_cbc, "sm4");
++    EVP_add_cipher_alias(SN_sm4_ecb, "SMS4-ECB");
++    EVP_add_cipher_alias(SN_sm4_ecb, "sms4-ecb");
++    EVP_add_cipher_alias(SN_sm4_cbc, "SMS4-CBC");
++    EVP_add_cipher_alias(SN_sm4_cbc, "sms4-cbc");
++    EVP_add_cipher_alias(SN_sm4_cfb128, "SMS4-CFB");
++    EVP_add_cipher_alias(SN_sm4_cfb128, "sms4-cfb");
++    EVP_add_cipher_alias(SN_sm4_ofb128, "SMS4-OFB");
++    EVP_add_cipher_alias(SN_sm4_ofb128, "sms4-ofb");
+ #endif
+ 
+ #ifndef OPENSSL_NO_RC2
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94818.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94818.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94818.patch	(working copy)
@@ -0,0 +1,20 @@
+diff -urN openssl-1.1.1d-old/crypto/asn1/a_strex.c openssl-1.1.1d/crypto/asn1/a_strex.c
+--- openssl-1.1.1d-old/crypto/asn1/a_strex.c	2020-05-27 04:18:27.045454773 -0400
++++ openssl-1.1.1d/crypto/asn1/a_strex.c	2020-05-27 04:20:23.606446568 -0400
+@@ -774,7 +774,7 @@
+ };
+ 
+ /* Copy from slb.h, need keep consistent */
+-#define MAX_OID_NUM		18 
++#define MAX_OID_NUM		19 
+ #define MAX_OIDNAME_LEN		32 
+ typedef struct slb_ssl_oidname_table {
+ 	unsigned char index;			/*Index of oid*/
+@@ -791,6 +791,7 @@
+ 	NID_generationQualifier,
+ 	NID_serialNumber,
+ 	NID_pkcs9_emailAddress,
++	NID_uniqueIdentifier,
+ 	NID_commonName,
+ 	NID_title,
+ 	NID_pseudonym,
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94844.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94844.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug94844.patch	(working copy)
@@ -0,0 +1,16 @@
+--- openssl-1.1.1d-old/crypto/evp/p_lib.c	2020-07-14 03:49:59.035789381 -0400
++++ openssl-1.1.1d-new/crypto/evp/p_lib.c	2020-09-03 05:29:52.587181050 -0400
+@@ -520,10 +520,12 @@
+ 
+ EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey)
+ {
+-    if (pkey->type != EVP_PKEY_EC) {
++    if ((pkey->type != EVP_PKEY_EC) && (pkey->type != EVP_PKEY_SM2)) {
+         EVPerr(EVP_F_EVP_PKEY_GET0_EC_KEY, EVP_R_EXPECTING_A_EC_KEY);
+         return NULL;
+     }
++    pkey->type = EVP_PKEY_EC;
++
+     return pkey->pkey.ec;
+ }
+ 
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug95954.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug95954.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-bug95954.patch	(working copy)
@@ -0,0 +1,43 @@
+diff -urN openssl-1.1.1d-old/crypto/asn1/a_verify.c openssl-1.1.1d/crypto/asn1/a_verify.c
+--- openssl-1.1.1d-old/crypto/asn1/a_verify.c	2019-09-10 09:13:07.000000000 -0400
++++ openssl-1.1.1d/crypto/asn1/a_verify.c	2020-07-14 06:49:27.039031372 -0400
+@@ -141,8 +141,12 @@
+ 
+         /* 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);
+-            goto err;
++		if (!((EVP_PKEY_type(pknid) == NID_X9_62_id_ecPublicKey) && (pkey->ameth->pkey_id == NID_sm2))) {
++            		ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
++            		goto err;
++		} else {
++			pkey->type = pkey->save_type = NID_X9_62_id_ecPublicKey;	
++		} 
+         }
+ 
+         if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
+diff -urN openssl-1.1.1d-old/ssl/statem/extensions_clnt.c openssl-1.1.1d/ssl/statem/extensions_clnt.c
+--- openssl-1.1.1d-old/ssl/statem/extensions_clnt.c	2019-09-10 09:13:07.000000000 -0400
++++ openssl-1.1.1d/ssl/statem/extensions_clnt.c	2020-07-14 06:49:05.634032879 -0400
+@@ -534,12 +534,15 @@
+     }
+ 
+     for (currv = max_version; currv >= min_version; currv--) {
+-        if (!WPACKET_put_bytes_u16(pkt, currv)) {
+-            SSLfatal(s, SSL_AD_INTERNAL_ERROR,
+-                     SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS,
+-                     ERR_R_INTERNAL_ERROR);
+-            return EXT_RETURN_FAIL;
+-        }
++	if (ssl_check_ustack_support_version(currv, s->ustack_version)) {
++		if (!WPACKET_put_bytes_u16(pkt, currv)) {
++        	    SSLfatal(s, SSL_AD_INTERNAL_ERROR,
++        	             SSL_F_TLS_CONSTRUCT_CTOS_SUPPORTED_VERSIONS,
++        	             ERR_R_INTERNAL_ERROR);
++        	    return EXT_RETURN_FAIL;
++        	}
++	}	
++        
+     }
+     if (!WPACKET_close(pkt) || !WPACKET_close(pkt)) {
+         SSLfatal(s, SSL_AD_INTERNAL_ERROR,
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-cve-2021-23841.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-cve-2021-23841.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-cve-2021-23841.patch	(working copy)
@@ -0,0 +1,13 @@
+diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
+index 833bfce..247ead3 100644
+--- a/crypto/x509/x509_cmp.c
++++ b/crypto/x509/x509_cmp.c
+@@ -39,6 +39,8 @@ unsigned long X509_issuer_and_serial_hash(X509 *a)
+     if (ctx == NULL)
+         goto err;
+     f = X509_NAME_oneline(a->cert_info.issuer, NULL, 0);
++    if (f == NULL)
++        goto err;
+     if (!EVP_DigestInit_ex(ctx, EVP_md5(), NULL))
+         goto err;
+     if (!EVP_DigestUpdate(ctx, (unsigned char *)f, strlen(f)))
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-sm2.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-sm2.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/openssl-1.1.1d-sm2.patch	(working copy)
@@ -0,0 +1,984 @@
+diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h
+index e74de55..7cb7d1c 100644
+--- a/crypto/asn1/standard_methods.h
++++ b/crypto/asn1/standard_methods.h
+@@ -56,6 +56,7 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
+ #endif
+ #ifndef OPENSSL_NO_SM2
+     &sm2_asn1_meth,
++    &sm2key_asn1_meth,
+ #endif
+ };
+ 
+diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c
+index c086f47..29b69d1 100644
+--- a/crypto/ec/ec_ameth.c
++++ b/crypto/ec/ec_ameth.c
+@@ -153,12 +153,20 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+     }
+ 
+     /* We have parameters now set public key */
++    if (eckey->group->curve_name == EVP_PKEY_SM2) {
++        int i=128;
++        unsigned tmpchar[128] = {0};
++        EncodeBase64(p, pklen, tmpchar, &i) ;
++    }
+     if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
+         ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+         goto ecerr;
+     }
+-
+-    EVP_PKEY_assign_EC_KEY(pkey, eckey);
++    if (eckey->group->curve_name == EVP_PKEY_SM2) {
++        EVP_PKEY_assign_SM2_KEY(pkey, eckey);
++    } else {
++        EVP_PKEY_assign_EC_KEY(pkey, eckey);
++    }
+     return 1;
+ 
+  ecerr:
+@@ -166,6 +174,46 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
+     return 0;
+ }
+ 
++static int sm2key_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
++{
++    const unsigned char *p = NULL;
++    void *pval;
++    int ptype, pklen;
++    EC_KEY *eckey = NULL;
++    X509_ALGOR *palg;
++
++    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
++        return 0;
++    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
++
++    eckey = eckey_type2param(ptype, pval);
++
++    if (!eckey)
++        {
++        ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
++        return 0;
++        }
++
++    /* We have parameters now set public key */
++    int i=128;
++    unsigned tmpchar[128] = {0};
++        EncodeBase64(p, pklen, tmpchar, &i) ;
++    if (!o2i_ECPublicKey(&eckey, &p, pklen))
++        {
++        ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
++        goto ecerr;
++        }
++
++    EVP_PKEY_assign_SM2_KEY(pkey, eckey);
++    return 1;
++
++    ecerr:
++    if (eckey)
++        EC_KEY_free(eckey);
++    return 0;
++}
++
++
+ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
+ {
+     int r;
+@@ -204,8 +252,13 @@ static int eckey_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8)
+         ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR);
+         goto ecerr;
+     }
++	if (eckey->group->curve_name == EVP_PKEY_SM2) {
+ 
++    EVP_PKEY_assign_SM2_KEY(pkey, eckey);
++	} else {
+     EVP_PKEY_assign_EC_KEY(pkey, eckey);
++	}
++
+     return 1;
+ 
+  ecliberr:
+@@ -411,7 +464,11 @@ static int eckey_param_decode(EVP_PKEY *pkey,
+         ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB);
+         return 0;
+     }
+-    EVP_PKEY_assign_EC_KEY(pkey, eckey);
++    if (eckey->group->curve_name == EVP_PKEY_SM2) {
++        EVP_PKEY_assign_SM2_KEY(pkey, eckey);
++    } else {
++        EVP_PKEY_assign_EC_KEY(pkey, eckey);
++    }
+     return 1;
+ }
+ 
+@@ -447,7 +504,11 @@ static int old_ec_priv_decode(EVP_PKEY *pkey,
+         ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR);
+         return 0;
+     }
+-    EVP_PKEY_assign_EC_KEY(pkey, ec);
++    if (ec->group->curve_name == EVP_PKEY_SM2) {
++        EVP_PKEY_assign_SM2_KEY(pkey, ec);
++    } else {
++        EVP_PKEY_assign_EC_KEY(pkey, ec);
++    }
+     return 1;
+ }
+ 
+@@ -611,9 +672,87 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
+ #if !defined(OPENSSL_NO_SM2)
+ const EVP_PKEY_ASN1_METHOD sm2_asn1_meth = {
+    EVP_PKEY_SM2,
+-   EVP_PKEY_EC,
+-   ASN1_PKEY_ALIAS
++   //EVP_PKEY_EC,
++   EVP_PKEY_SM2,
++   /*ASN1_PKEY_ALIAS*/ 0,
++    "SM2",
++    "OpenSSL SM2 algorithm",
++
++    //sm2key_pub_decode,
++    eckey_pub_decode,
++    eckey_pub_encode,
++    eckey_pub_cmp,
++    eckey_pub_print,
++
++    eckey_priv_decode,
++    eckey_priv_encode,
++    eckey_priv_print,
++
++    int_ec_size,
++    ec_bits,
++    ec_security_bits,
++
++    eckey_param_decode,
++    eckey_param_encode,
++    ec_missing_parameters,
++    ec_copy_parameters,
++    ec_cmp_parameters,
++    eckey_param_print,
++    0,
++
++    int_ec_free,
++    ec_pkey_ctrl,
++    old_ec_priv_decode,
++    old_ec_priv_encode,
++
++    0, 0, 0,
++
++    ec_pkey_check,
++    ec_pkey_public_check,
++    ec_pkey_param_check
+ };
++
++const EVP_PKEY_ASN1_METHOD sm2key_asn1_meth =
++    {
++    NID_sm2Encryption,
++    NID_sm2Encryption,
++    0,
++    "SM2",
++    "OpenSSL SM2 algorithm",
++
++    sm2key_pub_decode,
++    eckey_pub_encode,
++    eckey_pub_cmp,
++    eckey_pub_print,
++
++    eckey_priv_decode,
++    eckey_priv_encode,
++    eckey_priv_print,
++
++    int_ec_size,
++    ec_bits,
++    ec_security_bits,
++
++    eckey_param_decode,
++    eckey_param_encode,
++    ec_missing_parameters,
++    ec_copy_parameters,
++    ec_cmp_parameters,
++    eckey_param_print,
++    0,
++
++    int_ec_free,
++    ec_pkey_ctrl,
++    old_ec_priv_decode,
++    old_ec_priv_encode,
++
++    0, 0, 0,
++
++    ec_pkey_check,
++    ec_pkey_public_check,
++    ec_pkey_param_check
++    };
++
+ #endif
+ 
+ int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)
+diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
+index 454be16..936bcca 100644
+--- a/crypto/ec/ec_pmeth.c
++++ b/crypto/ec/ec_pmeth.c
+@@ -327,7 +327,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+             EVP_MD_type((const EVP_MD *)p2) != NID_sha3_224 &&
+             EVP_MD_type((const EVP_MD *)p2) != NID_sha3_256 &&
+             EVP_MD_type((const EVP_MD *)p2) != NID_sha3_384 &&
+-            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512) {
++            EVP_MD_type((const EVP_MD *)p2) != NID_sha3_512 &&
++	    EVP_MD_type((const EVP_MD *)p2) != NID_sm3) {
+             ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+             return 0;
+         }
+diff --git a/crypto/evp/c_alld.c b/crypto/evp/c_alld.c
+index 1267531..3423bd1 100644
+--- a/crypto/evp/c_alld.c
++++ b/crypto/evp/c_alld.c
+@@ -46,6 +46,8 @@ void openssl_add_all_digests_int(void)
+ #endif
+ #ifndef OPENSSL_NO_SM3
+     EVP_add_digest(EVP_sm3());
++    EVP_add_digest_alias(SN_sm3,"ssl2-sm3");
++    EVP_add_digest_alias(SN_sm3,"ssl3-sm3");
+ #endif
+ #ifndef OPENSSL_NO_BLAKE2
+     EVP_add_digest(EVP_blake2b512());
+diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
+index e61a876..0cbc20d 100644
+--- a/crypto/evp/evp_pkey.c
++++ b/crypto/evp/evp_pkey.c
+@@ -32,7 +32,7 @@ EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
+         return NULL;
+     }
+ 
+-    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
++    if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { 
+         EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+         i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
+         ERR_add_error_data(2, "TYPE=", obj_tmp);
+diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
+index 94e37f0..dbfd4c7 100644
+--- a/crypto/evp/m_sigver.c
++++ b/crypto/evp/m_sigver.c
+@@ -25,6 +25,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                           const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,
+                           int ver)
+ {
++    const unsigned char *sm2_id = "1234567812345678";
++    int sm2_id_len = 16;
++
+     if (ctx->pctx == NULL)
+         ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+     if (ctx->pctx == NULL)
+@@ -75,6 +78,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+         return 1;
+     if (!EVP_DigestInit_ex(ctx, type, e))
+         return 0;
++
++    if (pkey->type == EVP_PKEY_SM2) {
++    	if (EVP_PKEY_CTX_set1_id(ctx->pctx, sm2_id, sm2_id_len) <= 0) {
++    	    return 0;
++        }
++    }
+     /*
+      * This indicates the current algorithm requires
+      * special treatment before hashing the tbs-message.
+diff --git a/crypto/include/internal/asn1_int.h b/crypto/include/internal/asn1_int.h
+index 9c9b4d8..14842dd 100644
+--- a/crypto/include/internal/asn1_int.h
++++ b/crypto/include/internal/asn1_int.h
+@@ -83,7 +83,7 @@ extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
+ extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[2];
+ extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth;
+ extern const EVP_PKEY_ASN1_METHOD siphash_asn1_meth;
+-
++extern const EVP_PKEY_ASN1_METHOD sm2key_asn1_meth;
+ /*
+  * These are used internally in the ASN1_OBJECT to keep track of whether the
+  * names and data need to be free()ed
+diff --git a/crypto/include/internal/sm2.h b/crypto/include/internal/sm2.h
+index 5c5cd4b..53dc064 100644
+--- a/crypto/include/internal/sm2.h
++++ b/crypto/include/internal/sm2.h
+@@ -74,5 +74,6 @@ int sm2_decrypt(const EC_KEY *key,
+                 const uint8_t *ciphertext,
+                 size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len);
+ 
++
+ # endif /* OPENSSL_NO_SM2 */
+ #endif
+diff --git a/crypto/include/internal/sm3.h b/crypto/include/internal/sm3.h
+index 27eb471..58e06ba 100644
+--- a/crypto/include/internal/sm3.h
++++ b/crypto/include/internal/sm3.h
+@@ -35,5 +35,6 @@ int sm3_update(SM3_CTX *c, const void *data, size_t len);
+ int sm3_final(unsigned char *md, SM3_CTX *c);
+ 
+ void sm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
++void SM3(const uint8_t * message, uint32_t len, uint8_t * const digest);
+ 
+ #endif
+diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
+index ef2d1e0..44bc27f 100644
+--- a/crypto/objects/obj_dat.c
++++ b/crypto/objects/obj_dat.c
+@@ -30,6 +30,61 @@ DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj);
+ #define ADDED_LNAME     2
+ #define ADDED_NID       3
+ 
++int EncodeBase64(unsigned char *btSrc, int iSrcLen, unsigned char *btRet, int *piRetLen)
++{
++    int i = 0, j = 0, k = 0 ;
++    unsigned char EncodeBase64Map[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
++ 
++    if ((btSrc==NULL)||(iSrcLen<=0)) return -1;
++    k =  iSrcLen % 3 ;
++ 
++    if(k== 0)
++        i = (iSrcLen) / 3 * 4  ;
++    else
++        i = (iSrcLen) / 3 * 4 + 4 ;
++ 
++    if(btRet != NULL)
++    {
++        if(*piRetLen < i)
++            return -2 ;
++        *piRetLen = i ;
++    }
++    else
++    {
++        *piRetLen = i ;
++        return 0 ;
++    }
++ 
++    k = iSrcLen - iSrcLen % 3 ;
++    for(i=j=0; i<k; i+=3)
++    {
++        btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
++        btRet[j++] = EncodeBase64Map[((btSrc[i]<<4) + (btSrc[i+1]>>4))&0x3F] ;
++        btRet[j++] = EncodeBase64Map[((btSrc[i+1]<<2) + (btSrc[i+2]>>6))&0x3F] ;
++        btRet[j++] = EncodeBase64Map[btSrc[i+2]&0x3F] ;
++    }
++    k = iSrcLen - k ;
++    if(1 == k)
++    {
++        btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
++        btRet[j++] = EncodeBase64Map[(btSrc[i]<<4)&0x3F] ;
++        btRet[j++] = '=' ;
++        btRet[j++] = '=' ;
++ 
++    }
++    else if(2 == k)
++    {
++        btRet[j++] = EncodeBase64Map[(btSrc[i]>>2)&0x3F] ;
++        btRet[j++] = EncodeBase64Map[((btSrc[i]<<4) + (btSrc[i+1]>>4))&0x3F] ;
++        btRet[j++] = EncodeBase64Map[(btSrc[i+1]<<2)&0x3F] ;
++        btRet[j++] = '=' ;
++    }
++ 
++    *piRetLen = j ;
++    return *piRetLen ;
++}
++
++
+ struct added_obj_st {
+     int type;
+     ASN1_OBJECT *obj;
+diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
+index ea91db6..945a2b2 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[7779] = {
+     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,11 @@ 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,0x82,0x2D,0x01,  /* [7761] OBJ_sm2Encryption */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75,       /* [7770] OBJ_sm3WithSM2Encryption */
+ };
+ 
+-#define NUM_NID 1195
++#define NUM_NID 1197
+ static const ASN1_OBJECT nid_objs[NUM_NID] = {
+     {"UNDEF", "undefined", NID_undef},
+     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
+@@ -2275,9 +2277,11 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
+     {"magma-mac", "magma-mac", NID_magma_mac},
+     {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
+     {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
++    {"SM2ENC","sm2Encryption",NID_sm2Encryption,9,&(so[7761]),0},
++    {"SM2-SM3","sm3WithSM2Encryption",NID_sm3WithSM2Encryption,8,&(so[7770]),0},
+ };
+ 
+-#define NUM_SN 1186
++#define NUM_SN 1188
+ static const unsigned int sn_objs[NUM_SN] = {
+      364,    /* "AD_DVCS" */
+      419,    /* "AES-128-CBC" */
+@@ -2543,6 +2547,8 @@ static const unsigned int sn_objs[NUM_SN] = {
+     1100,    /* "SHAKE128" */
+     1101,    /* "SHAKE256" */
+     1172,    /* "SM2" */
++    1195,    /* "SM2ENC"*/
++    1196,    /* "SM2-SM3"*/
+     1143,    /* "SM3" */
+     1134,    /* "SM4-CBC" */
+     1137,    /* "SM4-CFB" */
+@@ -3467,7 +3473,7 @@ static const unsigned int sn_objs[NUM_SN] = {
+     1093,    /* "x509ExtAdmission" */
+ };
+ 
+-#define NUM_LN 1186
++#define NUM_LN 1188
+ static const unsigned int ln_objs[NUM_LN] = {
+      363,    /* "AD Time Stamping" */
+      405,    /* "ANSI X9.62" */
+@@ -4600,6 +4606,8 @@ static const unsigned int ln_objs[NUM_LN] = {
+     1062,    /* "siphash" */
+     1142,    /* "sm-scheme" */
+     1172,    /* "sm2" */
++    1195,    /* "sm2Encryption" */
++    1196,    /* "sm2-sm3" */   
+     1143,    /* "sm3" */
+     1144,    /* "sm3WithRSAEncryption" */
+     1134,    /* "sm4-cbc" */
+@@ -4657,7 +4665,7 @@ static const unsigned int ln_objs[NUM_LN] = {
+      125,    /* "zlib compression" */
+ };
+ 
+-#define NUM_OBJ 1071
++#define NUM_OBJ 1073
+ static const unsigned int obj_objs[NUM_OBJ] = {
+        0,    /* OBJ_undef                        0 */
+      181,    /* OBJ_iso                          1 */
+@@ -5126,6 +5134,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 */
++    1196,    /* OBJ_sm3WithSM2Encryption         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 */
+@@ -5338,6 +5347,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
+      439,    /* OBJ_pilotAttributeSyntax         0 9 2342 19200300 100 3 */
+      440,    /* OBJ_pilotObjectClass             0 9 2342 19200300 100 4 */
+      441,    /* OBJ_pilotGroups                  0 9 2342 19200300 100 10 */
++    1195,    /* OBJ_sm2Encryption                1 2 156 10197 1 301 1 */
+     1065,    /* OBJ_aria_128_ecb                 1 2 410 200046 1 1 1 */
+     1066,    /* OBJ_aria_128_cbc                 1 2 410 200046 1 1 2 */
+     1067,    /* OBJ_aria_128_cfb128              1 2 410 200046 1 1 3 */
+diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
+index 1b6a9c6..82a8490 100644
+--- a/crypto/objects/obj_mac.num
++++ b/crypto/objects/obj_mac.num
+@@ -1192,3 +1192,5 @@ magma_cfb		1191
+ magma_mac		1192
+ hmacWithSHA512_224		1193
+ hmacWithSHA512_256		1194
++sm2Encryption			1195
++sm3WithSM2Encryption	1196
+diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h
+index 9144d56..af59aba 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_sm3WithSM2Encryption, 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 ca3e744..2095067 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
++
++sm3WithSM2Encryption	sm3	sm2
+diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
+index 5b2bb54..d355427 100644
+--- a/crypto/objects/objects.txt
++++ b/crypto/objects/objects.txt
+@@ -381,9 +381,11 @@ rsadsi 2 6		:			: hmacWithMD5
+ rsadsi 2 7		:			: hmacWithSHA1
+ 
+ sm-scheme 301           : SM2                   : sm2
++sm-scheme 301 1         : SM2ENC                : sm2Encryption
+ 
+ sm-scheme 401           : SM3                   : sm3
+ sm-scheme 504           : RSA-SM3		: sm3WithRSAEncryption
++sm-scheme 501           : SM2-SM3		: sm3WithSM2Encryption
+ 
+ # From RFC4231
+ rsadsi 2 8		:			: hmacWithSHA224
+diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c
+index 4389fc7..39bac6d 100644
+--- a/crypto/sm2/sm2_crypt.c
++++ b/crypto/sm2/sm2_crypt.c
+@@ -391,3 +391,185 @@ int sm2_decrypt(const EC_KEY *key,
+ 
+     return rc;
+ }
++
++#if 0
++int array_sm2_decrypt(EC_KEY *eckey,
++		unsigned char *outputtext,
++		size_t *outputtext_len_bytes,
++		const unsigned char *ciphertext,
++		size_t ciphertext_len_bytes)
++{
++	int ret = 0;
++
++	ret = sm2_decrypt(eckey,
++			EVP_sm3(),
++			ciphertext,
++			ciphertext_len_bytes, outputtext, outputtext_len_bytes);
++	return ret;
++}
++#else
++
++#include "internal/sm3.h"
++
++static uint32_t kdf_sm3 (const uint8_t * z_input, const uint32_t z_len,
++                  const uint32_t klen, uint8_t const *outkey)
++{
++	#define SM3_DIGEST_SIZE 32
++    uint32_t i;
++
++    uint8_t *zz;
++
++    uint8_t digest[SM3_DIGEST_SIZE];
++
++    int rlen = klen;
++    uint8_t *pp = (uint8_t *) outkey;
++
++    zz = (unsigned char *) malloc (z_len + 4);
++    for (i = 0; i < z_len; i++)
++        zz[i] = z_input[i];
++
++    i = 1;
++    while (rlen > 0)
++    {
++        zz[z_len] = (i >> 24) & 0xff;
++        zz[z_len + 1] = (i >> 16) & 0xFF;
++        zz[z_len + 2] = (i >> 8) & 0xFF;
++        zz[z_len + 3] = i & 0xff;
++        SM3(zz, z_len + 4, digest);
++        memcpy (pp, digest, (rlen >= SM3_DIGEST_SIZE) ? SM3_DIGEST_SIZE : rlen);
++        rlen -= SM3_DIGEST_SIZE;
++        pp += SM3_DIGEST_SIZE;
++        i++;
++    }
++    rlen = 0;
++    for (i = 0; i < z_len; i++)
++        if (outkey[i] & 0xFF != 0)
++        {
++            rlen = 1;
++            break;
++        }
++    free ((void*)zz);
++    if (rlen > 0)
++    {
++        return (klen / SM3_DIGEST_SIZE + 1) * SM3_DIGEST_SIZE;
++    }
++    else
++    {
++        return 0;
++    }
++}
++
++
++int array_sm2_decrypt(EC_KEY *eckey,
++		unsigned char *outputtext,
++		unsigned int *outputtext_len_bytes,
++		const unsigned char *ciphertext,
++		unsigned int ciphertext_len_bytes)
++{
++	BIGNUM *da =NULL;
++        EC_POINT *tmp_point = NULL;
++	EC_GROUP *grp = NULL;
++        BN_CTX *ctx = NULL;
++        int ret = 0, i;
++        unsigned char *dec_key;
++        unsigned char digest[32]={0};
++
++#define DECRYPT_CLEAN(ret) \
++	if (!ret) { \
++		fflush(stdout); \
++	} \
++	if (ctx)\
++		BN_CTX_free(ctx); \
++	if (tmp_point)\
++		EC_POINT_free(tmp_point); \
++	if (dec_key)\
++		OPENSSL_free(dec_key)
++
++	
++
++	if(ciphertext_len_bytes<98)
++	    return ret;
++      
++        
++	grp = EC_KEY_get0_group(eckey);
++	if (!grp) {
++		return ret;
++	}
++
++	da = EC_KEY_get0_private_key(eckey);
++	if (!da) {
++		return ret;
++	}
++
++        if(!(dec_key = OPENSSL_malloc (ciphertext_len_bytes))){
++	    DECRYPT_CLEAN(0);
++	    return ret;
++	}
++
++        if (!(ctx = BN_CTX_new ()))
++        {
++            DECRYPT_CLEAN (0);
++            return ret;
++        }
++        if (!(tmp_point = EC_POINT_new (grp)))
++        {
++            DECRYPT_CLEAN (0);
++            return ret;
++        }
++
++//decrypting
++        //point octet length=65, because of SM2 only using uncompressed point octet
++        if (!EC_POINT_oct2point (grp, tmp_point, ciphertext, 65, ctx))
++        {
++            DECRYPT_CLEAN (0);
++            return ret;
++        }
++        if (!EC_POINT_is_on_curve (grp, tmp_point, ctx))
++        {
++            DECRYPT_CLEAN (0);  //testing C1 on curve?
++            return ret;
++        }
++        //[dB]C1=(x2,y2)
++        if (!EC_POINT_mul (grp, tmp_point, NULL, tmp_point, da, ctx))
++        {
++            DECRYPT_CLEAN (0);
++            return ret;
++        }
++        if (!EC_POINT_point2oct (grp, tmp_point, POINT_CONVERSION_UNCOMPRESSED, dec_key, 65, ctx))
++        {
++            DECRYPT_CLEAN (0);
++            return ret;
++        }
++        //construct key
++        //dec_key struct is 04 x2 y2 decrypting_key 
++        if(!kdf_sm3 (&dec_key[1], 64, ciphertext_len_bytes - 97, &dec_key[65])){
++	    DECRYPT_CLEAN(0);
++	    return ret;
++	}
++
++        for (i = 0; i < ciphertext_len_bytes - 97; i++)
++            outputtext[i] = ciphertext[i + 97] ^ dec_key[i + 65];
++        *outputtext_len_bytes = ciphertext_len_bytes - 97;
++
++	//verify
++	SM3_CTX sm3ctx;
++	sm3_init(&sm3ctx);
++	//x2
++	sm3_update(&sm3ctx,dec_key+1,32);
++	//M
++	sm3_update(&sm3ctx,outputtext,*outputtext_len_bytes);
++	//y2
++	sm3_update(&sm3ctx,dec_key+33,32);
++	sm3_final(digest,&sm3ctx);
++
++	for (i = 0; i < 32; i++)
++	   if (digest[i] != ciphertext[65 + i])
++	   {
++	       DECRYPT_CLEAN (0);
++	       return 0;
++	   }
++	DECRYPT_CLEAN (1);
++	return 1;
++}
++
++#endif
+diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
+index d187699..ce0c435 100644
+--- a/crypto/sm2/sm2_pmeth.c
++++ b/crypto/sm2/sm2_pmeth.c
+@@ -219,6 +219,10 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
+     case EVP_PKEY_CTRL_GET1_ID_LEN:
+         *(size_t *)p2 = smctx->id_len;
+         return 1;
++    case EVP_PKEY_CTRL_DIGESTINIT:
++    case EVP_PKEY_CTRL_PKCS7_SIGN:
++    case EVP_PKEY_CTRL_CMS_SIGN:
++        return 1;
+ 
+     default:
+         return -2;
+diff --git a/crypto/sm3/m_sm3.c b/crypto/sm3/m_sm3.c
+index 85538dc..f300ef1 100644
+--- a/crypto/sm3/m_sm3.c
++++ b/crypto/sm3/m_sm3.c
+@@ -29,7 +29,7 @@ static int final(EVP_MD_CTX *ctx, unsigned char *md)
+ {
+     return sm3_final(md, EVP_MD_CTX_md_data(ctx));
+ }
+-
++#if 0
+ static const EVP_MD sm3_md = {
+     NID_sm3,
+     NID_sm3WithRSAEncryption,
+@@ -43,6 +43,21 @@ static const EVP_MD sm3_md = {
+     SM3_CBLOCK,
+     sizeof(EVP_MD *) + sizeof(SM3_CTX),
+ };
++#else
++static const EVP_MD sm3_md = {
++    NID_sm3,
++    NID_sm3WithSM2Encryption,
++    SM3_DIGEST_LENGTH,
++    0,
++    init,
++    update,
++    final,
++    NULL,
++    NULL,
++    SM3_CBLOCK,
++    sizeof(EVP_MD *) + sizeof(SM3_CTX),
++};
++#endif
+ 
+ const EVP_MD *EVP_sm3(void)
+ {
+diff --git a/crypto/sm3/sm3.c b/crypto/sm3/sm3.c
+index 1588dd1..6603780 100644
+--- a/crypto/sm3/sm3.c
++++ b/crypto/sm3/sm3.c
+@@ -12,6 +12,15 @@
+ #include <openssl/e_os2.h>
+ #include "sm3_locl.h"
+ 
++void SM3(const uint8_t * message, uint32_t len, uint8_t * const digest)
++{
++	SM3_CTX ctx;
++
++	sm3_init(&ctx);
++	sm3_update(&ctx, message, len);
++	sm3_final(digest, &ctx);
++}
++
+ int sm3_init(SM3_CTX *c)
+ {
+     memset(c, 0, sizeof(*c));
+diff --git a/crypto/sm4/sm4.c b/crypto/sm4/sm4.c
+index 0c819a4..478fb27 100644
+--- a/crypto/sm4/sm4.c
++++ b/crypto/sm4/sm4.c
+@@ -231,3 +231,77 @@ void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY *ks)
+     store_u32_be(B1, out + 8);
+     store_u32_be(B0, out + 12);
+ }
++
++int sms4_ecb_encrypt(const uint8_t * in, const uint32_t in_len_bytes,
++             uint8_t * out, const SM4_KEY * key)
++{
++    int i, j, numBlocks, pc;
++    uint8_t tr[SM4_BLOCK_SIZE];
++    const uint32_t *rk;
++
++    pc = in_len_bytes & (SM4_BLOCK_SIZE - 1);
++    numBlocks = (in_len_bytes - pc) >> 4;
++    pc = SM4_BLOCK_SIZE - pc;
++
++    for (i = 0; i < numBlocks; i++)
++    {
++        for (j = 0; j < SM4_BLOCK_SIZE; j++)
++            tr[j] = in[i * SM4_BLOCK_SIZE + j];
++        /* sm4 encryption */
++        SM4_encrypt(tr, out + (i * SM4_BLOCK_SIZE), key);
++    }
++		/*NOPADDING for Array */
++#if 0
++#ifndef NOPADDING
++		/* process last block */
++		j = in_len_bytes - numBlocks * SM4_BLOCK_SIZE;
++		if (pc == 0)
++			pc = 16;
++		for (i = 0; i < j; i++)
++			tr[i] = in[numBlocks * SM4_BLOCK_SIZE + i];
++		for (i = j; i < 16; i++)
++			tr[i] = pc;
++	
++		SMS4_Encryption (tr, rk, out + numBlocks * SM4_BLOCK_SIZE);
++#endif
++#endif /* 0 for enable NOPADDING */
++
++   
++    return 1;
++}
++
++
++int sms4_ecb_decrypt(const uint8_t * in, const uint32_t in_len_bytes,
++            uint8_t * out,  const SM4_KEY * key)
++{
++    int i, j, numBlocks;
++    uint8_t tr[SM4_BLOCK_SIZE];
++
++    numBlocks = in_len_bytes / SM4_BLOCK_SIZE;
++
++    for (i = 0; i < numBlocks; i++)
++    {
++        for (j = 0; j < SM4_BLOCK_SIZE; j++) {
++            tr[j] = in[j + i * SM4_BLOCK_SIZE];
++        }
++        SM4_decrypt(tr, out + (i * SM4_BLOCK_SIZE), key);
++    }
++
++	/* add by xltx start */
++#if    0
++	/*NOPADDING for Array */
++#ifndef NOPADDING
++		*out_len_bytes = in_len_bytes - (out[in_len_bytes - 1] & 0xFF);
++#else
++		*out_len_bytes = in_len_bytes;
++#endif
++#endif
++	/* add by xltx end */
++
++    return 1;
++}
++
++int sms4_set_key(const uint8_t *key, SM4_KEY *ks)
++{
++	return SM4_set_key(key, ks);
++}
+diff --git a/include/openssl/evp.h b/include/openssl/evp.h
+index 545654a..081d63e 100644
+--- a/include/openssl/evp.h
++++ b/include/openssl/evp.h
+@@ -63,6 +63,11 @@
+ # define EVP_PKEY_X448 NID_X448
+ # define EVP_PKEY_ED448 NID_ED448
+ 
++#define EVP_PKEY_SM21  NID_sm2Encryption
++#define EVP_PKEY_SM21A NID_sm3WithSM2Encryption
++#define EVP_PKEY_SM21B NID_X9_62_id_ecPublicKey
++
++
+ #ifdef  __cplusplus
+ extern "C" {
+ #endif
+@@ -424,6 +429,11 @@ typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass,
+ #  define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                         (char *)(eckey))
+ # endif
++
++# ifndef OPENSSL_NO_SM2
++#  define EVP_PKEY_assign_SM2_KEY(pkey,eckey) EVP_PKEY_assign((pkey), EVP_PKEY_SM2,\
++                                        (char *)(eckey))
++# endif
+ # ifndef OPENSSL_NO_SIPHASH
+ #  define EVP_PKEY_assign_SIPHASH(pkey,shkey) EVP_PKEY_assign((pkey),EVP_PKEY_SIPHASH,\
+                                         (char *)(shkey))
+diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
+index 47dafe4..181acee 100644
+--- a/include/openssl/obj_mac.h
++++ b/include/openssl/obj_mac.h
+@@ -1174,6 +1174,16 @@
+ #define NID_sm3         1143
+ #define OBJ_sm3         OBJ_sm_scheme,401L
+ 
++#define SN_sm2Encryption                "SM2ENC"
++#define LN_sm2Encryption                "sm2Encryption"
++#define NID_sm2Encryption               1195
++#define OBJ_sm2Encryption               1L,2L,156L,10197L,1L,301L,1L
++
++#define SN_sm3WithSM2Encryption         "SM2-SM3"
++#define LN_sm3WithSM2Encryption         "sm3WithSM2Encryption"
++#define NID_sm3WithSM2Encryption                1196
++#define OBJ_sm3WithSM2Encryption                1L,2L,156L,10197L,1L,501L
++
+ #define SN_sm3WithRSAEncryption         "RSA-SM3"
+ #define LN_sm3WithRSAEncryption         "sm3WithRSAEncryption"
+ #define NID_sm3WithRSAEncryption                1144
+diff --git a/include/openssl/sm2_sm4_g.h b/include/openssl/sm2_sm4_g.h
+new file mode 100644
+index 0000000..3702557
+--- /dev/null
++++ b/include/openssl/sm2_sm4_g.h
+@@ -0,0 +1,47 @@
++/*
++ * Copyright 1995-2016 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
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++
++#ifndef HEADER_SM2_SM4_G_H
++# define HEADER_SM2_SM4_G_H
++
++#include <openssl/opensslconf.h>
++#include <openssl/ossl_typ.h>
++
++
++#include <stddef.h>
++#ifdef  __cplusplus
++extern "C" {
++#endif
++
++# ifndef OPENSSL_NO_SM4
++#define SM4_KEY_SCHEDULE  32
++typedef struct SM4_KEY_st {
++     unsigned int rk[SM4_KEY_SCHEDULE];
++} SM4_KEY;
++
++int sms4_set_key(const unsigned char *key, SM4_KEY *ks);
++int sms4_ecb_decrypt(const unsigned char * in, const unsigned int in_len_bytes,
++						 unsigned char * out,  const SM4_KEY * key);
++# endif
++
++# ifndef OPENSSL_NO_SM2
++
++int array_sm2_decrypt(EC_KEY *eckey,
++                unsigned char *outputtext,
++                unsigned int *outputtext_len_bytes,
++                const unsigned char *ciphertext,
++                unsigned int ciphertext_len_bytes);
++#endif
++
++# ifdef  __cplusplus
++}
++# endif
++
++
++#endif
+diff --git a/util/libcrypto.num b/util/libcrypto.num
+index 27d428b..14c1cef 100644
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -4583,3 +4583,6 @@ EVP_PKEY_get0_engine                    4536	1_1_1c	EXIST::FUNCTION:ENGINE
+ X509_get0_authority_serial              4537	1_1_1d	EXIST::FUNCTION:
+ X509_get0_authority_issuer              4538	1_1_1d	EXIST::FUNCTION:
+ X509_NAME_print_ex_for_certm            4539    1_1_1d  EXIST::FUNCTION:
++array_sm2_decrypt                       4540    1_1_1d  EXIST::FUNCTION:SM2
++sms4_set_key                            4541    1_1_1d  EXIST::FUNCTION:SM4
++sms4_ecb_decrypt                        4542    1_1_1d  EXIST::FUNCTION:SM4
Index: /branches/rel_ag_9_4_5/ssl-111/d_patch/sm4_gcm_ccm.patch
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/d_patch/sm4_gcm_ccm.patch	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/d_patch/sm4_gcm_ccm.patch	(working copy)
@@ -0,0 +1,2246 @@
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/apps/openssl-vms.cnf openssl-1.1.1d/apps/openssl-vms.cnf
+--- openssl-1.1.1d-no-sm4-gcm/apps/openssl-vms.cnf	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/apps/openssl-vms.cnf	2021-12-02 11:09:09.494296562 +0800
+@@ -148,7 +148,7 @@
+ #organizationalUnitName_default	=
+ 
+ commonName			= Common Name (e.g. server FQDN or YOUR name)
+-commonName_max			= 64
++commonName_max			= 128
+ 
+ emailAddress			= Email Address
+ emailAddress_max		= 64
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/ec/ec_ameth.c openssl-1.1.1d/crypto/ec/ec_ameth.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/ec/ec_ameth.c	2021-10-15 17:04:01.627776682 +0800
++++ openssl-1.1.1d/crypto/ec/ec_ameth.c	2021-12-02 11:09:09.494296562 +0800
+@@ -190,7 +190,6 @@
+ 
+     if (!eckey)
+         {
+-        ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB);
+         return 0;
+         }
+ 
+@@ -200,7 +199,6 @@
+         EncodeBase64(p, pklen, tmpchar, &i) ;
+     if (!o2i_ECPublicKey(&eckey, &p, pklen))
+         {
+-        ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR);
+         goto ecerr;
+         }
+ 
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/build.info openssl-1.1.1d/crypto/evp/build.info
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/build.info	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/crypto/evp/build.info	2021-12-02 11:09:09.494296562 +0800
+@@ -2,7 +2,7 @@
+ SOURCE[../../libcrypto]=\
+         encode.c digest.c evp_enc.c evp_key.c evp_cnf.c \
+         e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
+-        e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c \
++        e_rc4.c e_aes.c names.c e_seed.c e_aria.c e_sm4.c e_sms4_gcm.c e_sms4_ccm.c \
+         e_xcbc_d.c e_rc2.c e_cast.c e_rc5.c \
+         m_null.c m_md2.c m_md4.c m_md5.c m_sha1.c m_wp.c \
+         m_md5_sha1.c m_mdc2.c m_ripemd.c m_sha3.c \
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/c_allc.c openssl-1.1.1d/crypto/evp/c_allc.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/c_allc.c	2021-10-15 17:04:01.640776681 +0800
++++ openssl-1.1.1d/crypto/evp/c_allc.c	2021-12-02 11:09:09.494296562 +0800
+@@ -85,6 +85,9 @@
+     EVP_add_cipher(EVP_sm4_cfb());
+     EVP_add_cipher(EVP_sm4_ofb());
+     EVP_add_cipher(EVP_sm4_ctr());
++    EVP_add_cipher(EVP_sms4());
++    EVP_add_cipher(EVP_sms4_gcm());
++    EVP_add_cipher(EVP_sms4_ccm());
+     EVP_add_cipher_alias(SN_sm4_cbc, "SM4");
+     EVP_add_cipher_alias(SN_sm4_cbc, "sm4");
+     EVP_add_cipher_alias(SN_sm4_ecb, "SMS4-ECB");
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sm4.c openssl-1.1.1d/crypto/evp/e_sm4.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sm4.c	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/crypto/evp/e_sm4.c	2021-12-02 11:09:09.494296562 +0800
+@@ -92,9 +92,24 @@
+     NULL, NULL, NULL, NULL
+ };
+ 
++static const EVP_CIPHER sms4_mode = {
++    NID_sms4_cbc, 16, 16, 16,
++    EVP_CIPH_FLAG_DEFAULT_ASN1|EVP_CIPH_CBC_MODE,
++    sm4_init_key,
++    sm4_cbc_cipher,
++    NULL,
++    sizeof(EVP_SM4_KEY),
++    NULL, NULL, NULL, NULL
++};
++
+ const EVP_CIPHER *EVP_sm4_ctr(void)
+ {
+     return &sm4_ctr_mode;
+ }
+ 
++const EVP_CIPHER *EVP_sms4(void)
++{
++    return &sms4_mode;
++}
++
+ #endif
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sms4_ccm.c openssl-1.1.1d/crypto/evp/e_sms4_ccm.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sms4_ccm.c	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/evp/e_sms4_ccm.c	2021-12-02 11:09:09.495296562 +0800
+@@ -0,0 +1,341 @@
++/* ====================================================================
++ * Copyright (c) 2014 - 2017 The GmSSL Project.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in
++ *    the documentation and/or other materials provided with the
++ *    distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ *    software must display the following acknowledgment:
++ *    "This product includes software developed by the GmSSL Project.
++ *    (http://gmssl.org/)"
++ *
++ * 4. The name "GmSSL Project" must not be used to endorse or promote
++ *    products derived from this software without prior written
++ *    permission. For written permission, please contact
++ *    guanzhi1980@gmail.com.
++ *
++ * 5. Products derived from this software may not be called "GmSSL"
++ *    nor may "GmSSL" appear in their names without prior written
++ *    permission of the GmSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ *    acknowledgment:
++ *    "This product includes software developed by the GmSSL Project
++ *    (http://gmssl.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE GmSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ */
++ /*
++ * Copyright 2001-2016 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
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++
++#include <stdio.h>
++#include <string.h>
++
++#include <openssl/ossl_typ.h>
++#include <internal/evp_int.h>
++#include <openssl/crypto.h>
++#include <openssl/objects.h>
++#include "evp_local.h"
++#include "../modes/modes_local.h"
++
++#ifndef OPENSSL_NO_SMS4
++
++#include <openssl/sms4.h>
++
++typedef struct {
++    union {
++        double align;
++        sms4_key_t ks;
++    } ks;                       /* SMS4 key schedule to use */
++    int key_set;                /* Set if key initialised */
++    int iv_set;                 /* Set if an iv is set */
++    int tag_set;                /* Set if tag is valid */
++    int len_set;                /* Set if message length set */
++    int L, M;                   /* L and M parameters from RFC3610 */
++    int tls_aad_len;            /* TLS AAD length */
++    CCM128_CONTEXT ccm;
++    ccm128_f str;
++} EVP_SMS4_CCM_CTX;
++
++static int sms4_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
++{
++    EVP_SMS4_CCM_CTX *cctx = EVP_C_DATA(EVP_SMS4_CCM_CTX,c);
++    switch (type) {
++    case EVP_CTRL_INIT:
++        cctx->key_set = 0;
++        cctx->iv_set = 0;
++        cctx->L = 8;
++        cctx->M = 12;
++        cctx->tag_set = 0;
++        cctx->len_set = 0;
++        cctx->tls_aad_len = -1;
++        return 1;
++
++    case EVP_CTRL_AEAD_TLS1_AAD:
++        /* Save the AAD for later use */
++        if (arg != EVP_AEAD_TLS1_AAD_LEN)
++            return 0;
++        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
++        cctx->tls_aad_len = arg;
++        {
++            uint16_t len =
++                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
++                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
++            /* Correct length for explicit IV */
++            len -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
++            /* If decrypting correct for tag too */
++            if (!EVP_CIPHER_CTX_encrypting(c))
++                len -= cctx->M;
++            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
++            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
++        }
++        /* Extra padding: tag appended to record */
++        return cctx->M;
++
++    case EVP_CTRL_CCM_SET_IV_FIXED:
++        /* Sanity check length */
++        if (arg != EVP_CCM_TLS_FIXED_IV_LEN)
++            return 0;
++        /* Just copy to first part of IV */
++        memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg);
++        return 1;
++
++    case EVP_CTRL_AEAD_SET_IVLEN:
++        arg = 15 - arg;
++    case EVP_CTRL_CCM_SET_L:
++        if (arg < 2 || arg > 8)
++            return 0;
++        cctx->L = arg;
++        return 1;
++
++    case EVP_CTRL_AEAD_SET_TAG:
++        if ((arg & 1) || arg < 4 || arg > 16)
++            return 0;
++        if (EVP_CIPHER_CTX_encrypting(c) && ptr)
++            return 0;
++        if (ptr) {
++            cctx->tag_set = 1;
++            memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
++        }
++        cctx->M = arg;
++        return 1;
++
++    case EVP_CTRL_AEAD_GET_TAG:
++        if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set)
++            return 0;
++        if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg))
++            return 0;
++        cctx->tag_set = 0;
++        cctx->iv_set = 0;
++        cctx->len_set = 0;
++        return 1;
++
++    case EVP_CTRL_COPY:
++        {
++            EVP_CIPHER_CTX *out = ptr;
++            EVP_SMS4_CCM_CTX *cctx_out = EVP_C_DATA(EVP_SMS4_CCM_CTX,out);
++            if (cctx->ccm.key) {
++                if (cctx->ccm.key != &cctx->ks)
++                    return 0;
++                cctx_out->ccm.key = &cctx_out->ks;
++            }
++            return 1;
++        }
++
++    default:
++        return -1;
++
++    }
++}
++
++static int sms4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
++                             const unsigned char *iv, int enc)
++{
++    EVP_SMS4_CCM_CTX *cctx = EVP_C_DATA(EVP_SMS4_CCM_CTX,ctx);
++    if (!iv && !key)
++        return 1;
++    if (key)
++        do {
++            sms4_set_encrypt_key(&cctx->ks.ks, key);
++            CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
++                               &cctx->ks, (block128_f) sms4_encrypt);
++            cctx->str = NULL;
++            cctx->key_set = 1;
++        } while (0);
++    if (iv) {
++        memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L);
++        cctx->iv_set = 1;
++    }
++    return 1;
++}
++
++static int sms4_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++                               const unsigned char *in, size_t len)
++{
++    EVP_SMS4_CCM_CTX *cctx = EVP_C_DATA(EVP_SMS4_CCM_CTX,ctx);
++    CCM128_CONTEXT *ccm = &cctx->ccm;
++    /* Encrypt/decrypt must be performed in place */
++    if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M))
++        return -1;
++    /* If encrypting set explicit IV from sequence number (start of AAD) */
++    if (EVP_CIPHER_CTX_encrypting(ctx))
++        memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx),
++               EVP_CCM_TLS_EXPLICIT_IV_LEN);
++    /* Get rest of IV from explicit IV */
++    memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in,
++           EVP_CCM_TLS_EXPLICIT_IV_LEN);
++    /* Correct length value */
++    len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
++    if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L,
++                            len))
++            return -1;
++    /* Use saved AAD */
++    CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len);
++    /* Fix buffer to point to payload */
++    in += EVP_CCM_TLS_EXPLICIT_IV_LEN;
++    out += EVP_CCM_TLS_EXPLICIT_IV_LEN;
++    if (EVP_CIPHER_CTX_encrypting(ctx)) {
++        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
++                                                    cctx->str) :
++            CRYPTO_ccm128_encrypt(ccm, in, out, len))
++            return -1;
++        if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M))
++            return -1;
++        return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M;
++    } else {
++        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
++                                                     cctx->str) :
++            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
++            unsigned char tag[16];
++            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
++                if (!CRYPTO_memcmp(tag, in + len, cctx->M))
++                    return len;
++            }
++        }
++        OPENSSL_cleanse(out, len);
++        return -1;
++    }
++}
++
++static int sms4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++                           const unsigned char *in, size_t len)
++{
++    EVP_SMS4_CCM_CTX *cctx = EVP_C_DATA(EVP_SMS4_CCM_CTX,ctx);
++    CCM128_CONTEXT *ccm = &cctx->ccm;
++    /* If not set up, return error */
++    if (!cctx->key_set)
++        return -1;
++
++    if (cctx->tls_aad_len >= 0)
++        return sms4_ccm_tls_cipher(ctx, out, in, len);
++
++    if (!cctx->iv_set)
++        return -1;
++
++    if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
++        return -1;
++    if (!out) {
++        if (!in) {
++            if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
++                                    15 - cctx->L, len))
++                return -1;
++            cctx->len_set = 1;
++            return len;
++        }
++        /* If have AAD need message length */
++        if (!cctx->len_set && len)
++            return -1;
++        CRYPTO_ccm128_aad(ccm, in, len);
++        return len;
++    }
++    /* EVP_*Final() doesn't return any data */
++    if (!in)
++        return 0;
++    /* If not set length yet do it */
++    if (!cctx->len_set) {
++        if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
++                                15 - cctx->L, len))
++            return -1;
++        cctx->len_set = 1;
++    }
++    if (EVP_CIPHER_CTX_encrypting(ctx)) {
++        if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len,
++                                                    cctx->str) :
++            CRYPTO_ccm128_encrypt(ccm, in, out, len))
++            return -1;
++        cctx->tag_set = 1;
++        return len;
++    } else {
++        int rv = -1;
++        if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len,
++                                                     cctx->str) :
++            !CRYPTO_ccm128_decrypt(ccm, in, out, len)) {
++            unsigned char tag[16];
++            if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) {
++                if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx),
++                                   cctx->M))
++                    rv = len;
++            }
++        }
++        if (rv == -1)
++            OPENSSL_cleanse(out, len);
++        cctx->iv_set = 0;
++        cctx->tag_set = 0;
++        cctx->len_set = 0;
++        return rv;
++    }
++}
++
++# define SMS4_CCM_BLOCK_SIZE	1
++# define SMS4_CCM_IV_LENGTH	7
++
++# define SMS4_CCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
++                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
++                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
++                | EVP_CIPH_CUSTOM_COPY \
++		| EVP_CIPH_FLAG_AEAD_CIPHER)
++
++static const EVP_CIPHER sms4_ccm_mode = {
++	NID_sms4_ccm,
++	SMS4_CCM_BLOCK_SIZE,
++	SMS4_KEY_LENGTH,
++	SMS4_CCM_IV_LENGTH,
++	SMS4_CCM_FLAGS,
++	sms4_ccm_init_key,
++	sms4_ccm_cipher,
++	NULL,
++	sizeof(EVP_SMS4_CCM_CTX),
++	NULL, NULL, sms4_ccm_ctrl, NULL
++};
++
++const EVP_CIPHER *EVP_sms4_ccm(void) {
++	return &sms4_ccm_mode;
++}
++#endif /* OPENSSL_NO_SMS4 */
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sms4_gcm.c openssl-1.1.1d/crypto/evp/e_sms4_gcm.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/e_sms4_gcm.c	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/evp/e_sms4_gcm.c	2021-12-02 11:14:16.054280015 +0800
+@@ -0,0 +1,489 @@
++/* ====================================================================
++ * Copyright (c) 2014 - 2017 The GmSSL Project.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in
++ *    the documentation and/or other materials provided with the
++ *    distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ *    software must display the following acknowledgment:
++ *    "This product includes software developed by the GmSSL Project.
++ *    (http://gmssl.org/)"
++ *
++ * 4. The name "GmSSL Project" must not be used to endorse or promote
++ *    products derived from this software without prior written
++ *    permission. For written permission, please contact
++ *    guanzhi1980@gmail.com.
++ *
++ * 5. Products derived from this software may not be called "GmSSL"
++ *    nor may "GmSSL" appear in their names without prior written
++ *    permission of the GmSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ *    acknowledgment:
++ *    "This product includes software developed by the GmSSL Project
++ *    (http://gmssl.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE GmSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ */
++ /*
++ * Copyright 2001-2016 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
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++
++#include <stdio.h>
++#include <string.h>
++
++#include <openssl/ossl_typ.h>
++#include <internal/evp_int.h>
++#include <openssl/evp.h>
++#include <openssl/rand.h>
++#include <openssl/crypto.h>
++#include <openssl/objects.h>
++#include <openssl/obj_mac.h>
++#include <openssl/modes.h>
++#include "evp_local.h"
++#include "../modes/modes_local.h"
++
++#ifndef OPENSSL_NO_SMS4
++
++#include <openssl/sms4.h>
++
++typedef struct {
++    union {
++        double align;
++        sms4_key_t ks;
++    } ks;                       /* SMS4 key schedule to use */
++    int key_set;                /* Set if key initialised */
++    int iv_set;                 /* Set if an iv is set */
++    GCM128_CONTEXT gcm;
++    unsigned char *iv;          /* Temporary IV store */
++    int ivlen;                  /* IV length */
++    int taglen;
++    int iv_gen;                 /* It is OK to generate IVs */
++    int tls_aad_len;            /* TLS AAD length */
++    ctr128_f ctr;
++} EVP_SMS4_GCM_CTX;
++
++
++static int sms4_gcm_cleanup(EVP_CIPHER_CTX *c)
++{
++    EVP_SMS4_GCM_CTX *gctx = EVP_C_DATA(EVP_SMS4_GCM_CTX,c);
++    OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
++    if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
++        OPENSSL_free(gctx->iv);
++    return 1;
++}
++
++#if 0
++#define PRINTF(label, buf, len) do { \
++   int ivenky;                                 \
++   printf("%s. %s [%d bytes]:\n", __FUNCTION__, (label), (len));        \
++   for (ivenky = 0; ivenky < (len); ivenky++) {\
++      printf("0x%02x%s", (buf)[ivenky],  (ivenky % 8 == 7) ? "\n" : ", ");	\
++   }\
++   printf("\n"); \
++} while (0)
++#define ssl_dbg_printf(format, args...) printf(format, ## args)
++#else
++#define PRINTF(label, buf, len)
++#define ssl_dbg_printf(format, args...)
++#endif
++
++
++/* increment counter (64-bit int) by 1 */
++static void ctr64_inc(unsigned char *counter)
++{
++    int n = 8;
++    unsigned char c;
++
++    do {
++        --n;
++        c = counter[n];
++        ++c;
++        counter[n] = c;
++        if (c)
++            return;
++    } while (n);
++}
++
++static int sms4_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
++{
++    EVP_SMS4_GCM_CTX *gctx = EVP_C_DATA(EVP_SMS4_GCM_CTX,c);
++    switch (type) {
++    case EVP_CTRL_INIT:
++        gctx->key_set = 0;
++        gctx->iv_set = 0;
++        gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
++        gctx->iv = EVP_CIPHER_CTX_iv_noconst(c);
++        gctx->taglen = -1;
++        gctx->iv_gen = 0;
++        gctx->tls_aad_len = -1;
++        return 1;
++
++    case EVP_CTRL_GET_IVLEN:
++        *(int *)ptr = gctx->ivlen;
++        return 1;
++
++    case EVP_CTRL_AEAD_SET_IVLEN:
++        if (arg <= 0)
++            return 0;
++        /* Allocate memory for IV if needed */
++        if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) {
++            if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c))
++                OPENSSL_free(gctx->iv);
++            gctx->iv = OPENSSL_malloc(arg);
++            if (gctx->iv == NULL)
++                return 0;
++        }
++        gctx->ivlen = arg;
++        return 1;
++
++    case EVP_CTRL_AEAD_SET_TAG:
++        if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c))
++            return 0;
++        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
++        gctx->taglen = arg;
++        return 1;
++
++    case EVP_CTRL_AEAD_GET_TAG:
++        if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c)
++            || gctx->taglen < 0)
++            return 0;
++        memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg);
++        return 1;
++
++    case EVP_CTRL_GCM_SET_IV_FIXED:
++        /* Special case: -1 length restores whole IV */
++        if (arg == -1) {
++            memcpy(gctx->iv, ptr, gctx->ivlen);
++            gctx->iv_gen = 1;
++            return 1;
++        }
++        /*
++         * Fixed field must be at least 4 bytes and invocation field at least
++         * 8.
++         */
++        if ((arg < 4) || (gctx->ivlen - arg) < 8)
++            return 0;
++        if (arg)
++            memcpy(gctx->iv, ptr, arg);
++        if (EVP_CIPHER_CTX_encrypting(c)
++            && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
++            return 0;
++        gctx->iv_gen = 1;
++        return 1;
++
++    case EVP_CTRL_GCM_IV_GEN:
++        if (gctx->iv_gen == 0 || gctx->key_set == 0)
++            return 0;
++        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
++        if (arg <= 0 || arg > gctx->ivlen)
++            arg = gctx->ivlen;
++        memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
++        /*
++         * Invocation field will be at least 8 bytes in size and so no need
++         * to check wrap around or increment more than last 8 bytes.
++         */
++        ctr64_inc(gctx->iv + gctx->ivlen - 8);
++        gctx->iv_set = 1;
++        return 1;
++
++    case EVP_CTRL_GCM_SET_IV_INV:
++        if (gctx->iv_gen == 0 || gctx->key_set == 0
++            || EVP_CIPHER_CTX_encrypting(c))
++            return 0;
++        memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
++        CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen);
++        gctx->iv_set = 1;
++        return 1;
++
++    case EVP_CTRL_AEAD_TLS1_AAD:
++        /* Save the AAD for later use */
++        if (arg != EVP_AEAD_TLS1_AAD_LEN)
++            return 0;
++        memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg);
++        gctx->tls_aad_len = arg;
++        {
++            unsigned int len =
++                EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8
++                | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1];
++            /* Correct length for explicit IV */
++            len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
++            /* If decrypting correct for tag too */
++            if (!EVP_CIPHER_CTX_encrypting(c))
++                len -= EVP_GCM_TLS_TAG_LEN;
++            EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8;
++            EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff;
++        }
++        /* Extra padding: tag appended to record */
++        return EVP_GCM_TLS_TAG_LEN;
++
++    case EVP_CTRL_COPY:
++        {
++            EVP_CIPHER_CTX *out = ptr;
++            EVP_SMS4_GCM_CTX *gctx_out = EVP_C_DATA(EVP_SMS4_GCM_CTX,out);
++            if (gctx->gcm.key) {
++                if (gctx->gcm.key != &gctx->ks)
++                    return 0;
++                gctx_out->gcm.key = &gctx_out->ks;
++            }
++            if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c))
++                gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out);
++            else {
++                gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
++                if (gctx_out->iv == NULL)
++                    return 0;
++                memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
++            }
++            return 1;
++        }
++
++    default:
++        return -1;
++
++    }
++}
++
++static int sms4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
++                             const unsigned char *iv, int enc)
++{
++    EVP_SMS4_GCM_CTX *gctx = EVP_C_DATA(EVP_SMS4_GCM_CTX,ctx);
++    if (!iv && !key)
++        return 1;
++    if (key) {
++        do {
++            (void)0;        /* terminate potentially open 'else' */
++
++            sms4_set_encrypt_key(&gctx->ks.ks, key);
++            CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
++                               (block128_f)sms4_encrypt);
++            gctx->ctr = NULL;
++        } while (0);
++
++        /*
++         * If we have an iv can set it directly, otherwise use saved IV.
++         */
++        if (iv == NULL && gctx->iv_set)
++            iv = gctx->iv;
++        if (iv) {
++            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
++            gctx->iv_set = 1;
++        }
++        gctx->key_set = 1;
++    } else {
++        /* If key set use IV, otherwise copy */
++        if (gctx->key_set)
++            CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen);
++        else
++            memcpy(gctx->iv, iv, gctx->ivlen);
++        gctx->iv_set = 1;
++        gctx->iv_gen = 0;
++    }
++    return 1;
++}
++
++/*
++ * Handle TLS GCM packet format. This consists of the last portion of the IV
++ * followed by the payload and finally the tag. On encrypt generate IV,
++ * encrypt payload and write the tag. On verify retrieve IV, decrypt payload
++ * and verify tag.
++ */
++
++static int sms4_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++                               const unsigned char *in, size_t len)
++{
++    EVP_SMS4_GCM_CTX *gctx = EVP_C_DATA(EVP_SMS4_GCM_CTX,ctx);
++    int rv = -1;
++    /* Encrypt/decrypt must be performed in place */
++    if (out != in
++        || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN))
++        return -1;
++    /*
++     * Set IV from start of buffer or generate IV and write to start of
++     * buffer.
++     */
++    if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ?
++                            EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV,
++                            EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0)
++        goto err;
++    /* Use saved AAD */
++    if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
++                          gctx->tls_aad_len))
++        goto err;
++    /* Fix buffer and length to point to payload */
++    in += EVP_GCM_TLS_EXPLICIT_IV_LEN;
++    out += EVP_GCM_TLS_EXPLICIT_IV_LEN;
++    len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
++    if (EVP_CIPHER_CTX_encrypting(ctx)) {
++        /* Encrypt payload */
++        if (gctx->ctr) {
++            size_t bulk = 0;
++            if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
++                                            in + bulk,
++                                            out + bulk,
++                                            len - bulk, gctx->ctr))
++                goto err;
++        } else {
++            size_t bulk = 0;
++            if (CRYPTO_gcm128_encrypt(&gctx->gcm,
++                                      in + bulk, out + bulk, len - bulk))
++                goto err;
++        }
++        out += len;
++        /* Finally write tag */
++        CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN);
++        rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN;
++    } else {
++        /* Decrypt */
++        if (gctx->ctr) {
++            size_t bulk = 0;
++            if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
++                                            in + bulk,
++                                            out + bulk,
++                                            len - bulk, gctx->ctr))
++                goto err;
++        } else {
++            size_t bulk = 0;
++            if (CRYPTO_gcm128_decrypt(&gctx->gcm,
++                                      in + bulk, out + bulk, len - bulk))
++                goto err;
++        }
++        /* Retrieve tag */
++        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx),
++                          EVP_GCM_TLS_TAG_LEN);
++        /* If tag mismatch wipe buffer */
++        if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len,
++                          EVP_GCM_TLS_TAG_LEN)) {
++            OPENSSL_cleanse(out, len);
++            goto err;
++        }
++        rv = len;
++
++    }
++
++ err:
++    gctx->iv_set = 0;
++    gctx->tls_aad_len = -1;
++    return rv;
++}
++
++static int sms4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
++                           const unsigned char *in, size_t len)
++{
++    EVP_SMS4_GCM_CTX *gctx = EVP_C_DATA(EVP_SMS4_GCM_CTX,ctx);
++    /* If not set up, return error */
++    if (!gctx->key_set)
++        return -1;
++
++    if (gctx->tls_aad_len >= 0) {
++        return sms4_gcm_tls_cipher(ctx, out, in, len);
++    }
++
++    if (!gctx->iv_set)
++        return -1;
++    if (in) {
++        if (out == NULL) {
++            if (CRYPTO_gcm128_aad(&gctx->gcm, in, len))
++                return -1;
++        } else if (EVP_CIPHER_CTX_encrypting(ctx)) {
++            if (gctx->ctr) {
++                size_t bulk = 0;
++                if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm,
++                                                in + bulk,
++                                                out + bulk,
++                                                len - bulk, gctx->ctr))
++                    return -1;
++            } else {
++                size_t bulk = 0;
++                if (CRYPTO_gcm128_encrypt(&gctx->gcm,
++                                          in + bulk, out + bulk, len - bulk))
++                    return -1;
++            }
++        } else {
++            if (gctx->ctr) {
++                size_t bulk = 0;
++                if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm,
++                                                in + bulk,
++                                                out + bulk,
++                                                len - bulk, gctx->ctr))
++                    return -1;
++            } else {
++                size_t bulk = 0;
++                if (CRYPTO_gcm128_decrypt(&gctx->gcm,
++                                          in + bulk, out + bulk, len - bulk))
++                    return -1;
++            }
++        }
++        return len;
++    } else {
++        if (!EVP_CIPHER_CTX_encrypting(ctx)) {
++            if (gctx->taglen < 0)
++                return -1;
++            if (CRYPTO_gcm128_finish(&gctx->gcm,
++                                     EVP_CIPHER_CTX_buf_noconst(ctx),
++                                     gctx->taglen) != 0)
++                return -1;
++            gctx->iv_set = 0;
++            return 0;
++        }
++        CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16);
++        gctx->taglen = 16;
++        /* Don't reuse the IV */
++        gctx->iv_set = 0;
++        return 0;
++    }
++
++}
++
++# define SMS4_GCM_BLOCK_SIZE	1
++# define SMS4_GCM_IV_LENGTH	12
++
++# define SMS4_GCM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \
++                | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \
++                | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \
++                | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_GCM_MODE \
++                | EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV_LENGTH)
++
++static const EVP_CIPHER sms4_gcm_mode = {
++	NID_sms4_gcm,
++	SMS4_GCM_BLOCK_SIZE,
++	SMS4_KEY_LENGTH,
++	SMS4_GCM_IV_LENGTH,
++	SMS4_GCM_FLAGS,
++	sms4_gcm_init_key,
++	sms4_gcm_cipher,
++	sms4_gcm_cleanup,
++	sizeof(EVP_SMS4_GCM_CTX),
++	NULL, NULL, sms4_gcm_ctrl, NULL
++};
++
++const EVP_CIPHER *EVP_sms4_gcm(void) {
++	return &sms4_gcm_mode;
++}
++
++#endif /* OPENSSL_NO_SMS4 */
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/evp/evp_local.h openssl-1.1.1d/crypto/evp/evp_local.h
+--- openssl-1.1.1d-no-sm4-gcm/crypto/evp/evp_local.h	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/evp/evp_local.h	2021-12-02 11:09:09.495296562 +0800
+@@ -0,0 +1,69 @@
++/*
++ *  * Copyright 2000-2018 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
++ *      * in the file LICENSE in the source distribution or at
++ *       * https://www.openssl.org/source/license.html
++ *        */
++
++/* EVP_MD_CTX related stuff */
++
++struct evp_md_ctx_st {
++    const EVP_MD *digest;
++    ENGINE *engine;             /* functional reference if 'digest' is
++                                 * ENGINE-provided */
++    unsigned long flags;
++    void *md_data;
++    /* Public key context for sign/verify */
++    EVP_PKEY_CTX *pctx;    // lijk
++    /* Update function: usually copied from EVP_MD */
++    int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);
++} /* EVP_MD_CTX */ ;
++
++struct evp_cipher_ctx_st {
++    const EVP_CIPHER *cipher;
++    ENGINE *engine;             /* functional reference if 'cipher' is
++                                 * ENGINE-provided */
++    int encrypt;                /* encrypt or decrypt */
++    int buf_len;                /* number we have left */
++    unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */
++    unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */
++    unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */
++    int num;                    /* used by cfb/ofb/ctr mode */
++    /* FIXME: Should this even exist? It appears unused */
++    void *app_data;             /* application stuff */
++    int key_len;                /* May change for variable length cipher */
++    unsigned long flags;        /* Various flags */
++    void *cipher_data;          /* per EVP data */
++    int final_used;
++    int block_mask;
++    unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */
++} /* EVP_CIPHER_CTX */ ;
++
++int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass,
++                             int passlen, ASN1_TYPE *param,
++                             const EVP_CIPHER *c, const EVP_MD *md,
++                             int en_de);
++
++struct evp_Encode_Ctx_st {
++    /* number saved in a partial encode/decode */
++    int num;
++    /*
++ *      * The length is either the output line length (in input bytes) or the
++ *           * shortest input line length that is ok.  Once decoding begins, the
++ *                * length is adjusted up each time a longer line is decoded
++ *                     */
++    int length;
++    /* data to encode */
++    unsigned char enc_data[80];
++    /* number read on current line */
++    int line_num;
++    unsigned int flags;
++};
++
++typedef struct evp_pbe_st EVP_PBE_CTL;
++DEFINE_STACK_OF(EVP_PBE_CTL)
++
++int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
++
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/modes/modes_local.h openssl-1.1.1d/crypto/modes/modes_local.h
+--- openssl-1.1.1d-no-sm4-gcm/crypto/modes/modes_local.h	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/modes/modes_local.h	2021-12-02 11:09:09.495296562 +0800
+@@ -0,0 +1,191 @@
++/*
++ *  * Copyright 2010-2018 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
++ *      * in the file LICENSE in the source distribution or at
++ *       * https://www.openssl.org/source/license.html
++ *        */
++
++#include <openssl/modes.h>
++
++#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
++typedef __int64 i64;
++typedef unsigned __int64 u64;
++# define U64(C) C##UI64
++#elif defined(__arch64__)
++typedef long i64;
++typedef unsigned long u64;
++# define U64(C) C##UL
++#else
++typedef long long i64;
++typedef unsigned long long u64;
++# define U64(C) C##ULL
++#endif
++
++typedef unsigned int u32;
++typedef unsigned char u8;
++
++#define STRICT_ALIGNMENT 1
++#ifndef PEDANTIC
++# if defined(__i386)    || defined(__i386__)    || \
++     defined(__x86_64)  || defined(__x86_64__)  || \
++     defined(_M_IX86)   || defined(_M_AMD64)    || defined(_M_X64) || \
++     defined(__aarch64__)                       || \
++     defined(__s390__)  || defined(__s390x__)
++#  undef STRICT_ALIGNMENT
++# endif
++#endif
++
++#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
++# if defined(__GNUC__) && __GNUC__>=2
++#  if defined(__x86_64) || defined(__x86_64__)
++#   define BSWAP8(x) ({ u64 ret_=(x);                   \
++                        asm ("bswapq %0"                \
++                        : "+r"(ret_));   ret_;          })
++#   define BSWAP4(x) ({ u32 ret_=(x);                   \
++                        asm ("bswapl %0"                \
++                        : "+r"(ret_));   ret_;          })
++#  elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)
++#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
++                        asm ("bswapl %0; bswapl %1"     \
++                        : "+r"(hi_),"+r"(lo_));         \
++                        (u64)hi_<<32|lo_;               })
++#   define BSWAP4(x) ({ u32 ret_=(x);                   \
++                        asm ("bswapl %0"                \
++                        : "+r"(ret_));   ret_;          })
++#  elif defined(__aarch64__)
++#   define BSWAP8(x) ({ u64 ret_;                       \
++                        asm ("rev %0,%1"                \
++                        : "=r"(ret_) : "r"(x)); ret_;   })
++#   define BSWAP4(x) ({ u32 ret_;                       \
++                        asm ("rev %w0,%w1"              \
++                        : "=r"(ret_) : "r"(x)); ret_;   })
++#  elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT)
++#   define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x);   \
++                        asm ("rev %0,%0; rev %1,%1"     \
++                        : "+r"(hi_),"+r"(lo_));         \
++                        (u64)hi_<<32|lo_;               })
++#   define BSWAP4(x) ({ u32 ret_;                       \
++                        asm ("rev %0,%1"                \
++                        : "=r"(ret_) : "r"((u32)(x)));  \
++                        ret_;                           })
++#  endif
++# elif defined(_MSC_VER)
++#  if _MSC_VER>=1300
++#   include <stdlib.h>
++#   pragma intrinsic(_byteswap_uint64,_byteswap_ulong)
++#   define BSWAP8(x)    _byteswap_uint64((u64)(x))
++#   define BSWAP4(x)    _byteswap_ulong((u32)(x))
++#  elif defined(_M_IX86)
++__inline u32 _bswap4(u32 val)
++{
++_asm mov eax, val _asm bswap eax}
++#   define BSWAP4(x)    _bswap4(x)
++#  endif
++# endif
++#endif
++#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT)
++# define GETU32(p)       BSWAP4(*(const u32 *)(p))
++# define PUTU32(p,v)     *(u32 *)(p) = BSWAP4(v)
++#else
++# define GETU32(p)       ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3])
++# define PUTU32(p,v)     ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v))
++#endif
++/*- GCM definitions */ typedef struct {
++    u64 hi, lo;
++} u128;
++
++#ifdef  TABLE_BITS
++# undef  TABLE_BITS
++#endif
++/*
++ *  * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should
++ *   * never be set to 8 [or 1]. For further information see gcm128.c.
++ *    */
++#define TABLE_BITS 4
++
++struct gcm128_context {
++    /* Following 6 names follow names in GCM specification */
++    union {
++        u64 u[2];
++        u32 d[4];
++        u8 c[16];
++        size_t t[16 / sizeof(size_t)];
++    } Yi, EKi, EK0, len, Xi, H;
++    /*
++ *      * Relative position of Xi, H and pre-computed Htable is used in some
++ *           * assembler modules, i.e. don't change the order!
++ *                */
++#if TABLE_BITS==8
++    u128 Htable[256];
++#else
++    u128 Htable[16];
++    void (*gmult) (u64 Xi[2], const u128 Htable[16]);
++    void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp,
++                   size_t len);
++#endif
++    unsigned int mres, ares;
++    block128_f block;
++    void *key;
++#if !defined(OPENSSL_SMALL_FOOTPRINT)
++    unsigned char Xn[48];
++#endif
++};
++
++struct xts128_context {
++    void *key1, *key2;
++    block128_f block1, block2;
++};
++
++struct ccm128_context {
++    union {
++        u64 u[2];
++        u8 c[16];
++    } nonce, cmac;
++    u64 blocks;
++    block128_f block;
++    void *key;
++};
++
++#ifndef OPENSSL_NO_OCB
++
++typedef union {
++    u64 a[2];
++    unsigned char c[16];
++} OCB_BLOCK;
++# define ocb_block16_xor(in1,in2,out) \
++    ( (out)->a[0]=(in1)->a[0]^(in2)->a[0], \
++      (out)->a[1]=(in1)->a[1]^(in2)->a[1] )
++# if STRICT_ALIGNMENT
++#  define ocb_block16_xor_misaligned(in1,in2,out) \
++    ocb_block_xor((in1)->c,(in2)->c,16,(out)->c)
++# else
++#  define ocb_block16_xor_misaligned ocb_block16_xor
++# endif
++
++struct ocb128_context {
++    /* Need both encrypt and decrypt key schedules for decryption */
++    block128_f encrypt;
++    block128_f decrypt;
++    void *keyenc;
++    void *keydec;
++    ocb128_f stream;    /* direction dependent */
++    /* Key dependent variables. Can be reused if key remains the same */
++    size_t l_index;
++    size_t max_l_index;
++    OCB_BLOCK l_star;
++    OCB_BLOCK l_dollar;
++    OCB_BLOCK *l;
++    /* Must be reset for each session */
++    struct {
++        u64 blocks_hashed;
++        u64 blocks_processed;
++        OCB_BLOCK offset_aad;
++        OCB_BLOCK sum;
++        OCB_BLOCK offset;
++        OCB_BLOCK checksum;
++    } sess;
++};
++#endif                          /* OPENSSL_NO_OCB */
++
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_dat.h openssl-1.1.1d/crypto/objects/obj_dat.h
+--- openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_dat.h	2021-10-15 17:04:01.629776682 +0800
++++ openssl-1.1.1d/crypto/objects/obj_dat.h	2021-12-02 11:09:09.496296562 +0800
+@@ -2,7 +2,7 @@
+  * WARNING: do not edit!
+  * Generated by crypto/objects/obj_dat.pl
+  *
+- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1995-2021 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
+  * in the file LICENSE in the source distribution or at
+@@ -10,7 +10,7 @@
+  */
+ 
+ /* Serialized OID's */
+-static const unsigned char so[7779] = {
++static const unsigned char so[7802] = {
+     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,11 +1076,14 @@
+     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,0x82,0x2D,0x01,  /* [7761] OBJ_sm2Encryption */
+-    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75,       /* [7770] OBJ_sm3WithSM2Encryption */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D,0x01,  /* [ 7761] OBJ_sm2Encryption */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75,       /* [ 7770] OBJ_sm3WithSM2Encryption */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,            /* [ 7778] OBJ_sms4_cbc */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x08,       /* [ 7785] OBJ_sms4_gcm */
++    0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x09,       /* [ 7793] OBJ_sms4_ccm */
+ };
+ 
+-#define NUM_NID 1197
++#define NUM_NID 1200
+ static const ASN1_OBJECT nid_objs[NUM_NID] = {
+     {"UNDEF", "undefined", NID_undef},
+     {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
+@@ -2277,11 +2280,14 @@
+     {"magma-mac", "magma-mac", NID_magma_mac},
+     {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
+     {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
+-    {"SM2ENC","sm2Encryption",NID_sm2Encryption,9,&(so[7761]),0},
+-    {"SM2-SM3","sm3WithSM2Encryption",NID_sm3WithSM2Encryption,8,&(so[7770]),0},
++    {"SM2ENC", "sm2Encryption", NID_sm2Encryption, 9, &so[7761]},
++    {"SM2-SM3", "sm3WithSM2Encryption", NID_sm3WithSM2Encryption, 8, &so[7770]},
++    {"SMS4-CBC", "sms4-cbc", NID_sms4_cbc, 7, &so[7778]},
++    {"SMS4-GCM", "sms4-gcm", NID_sms4_gcm, 8, &so[7785]},
++    {"SMS4-CCM", "sms4-ccm", NID_sms4_ccm, 8, &so[7793]},
+ };
+ 
+-#define NUM_SN 1188
++#define NUM_SN 1191
+ static const unsigned int sn_objs[NUM_SN] = {
+      364,    /* "AD_DVCS" */
+      419,    /* "AES-128-CBC" */
+@@ -2547,8 +2553,8 @@
+     1100,    /* "SHAKE128" */
+     1101,    /* "SHAKE256" */
+     1172,    /* "SM2" */
+-    1195,    /* "SM2ENC"*/
+-    1196,    /* "SM2-SM3"*/
++    1196,    /* "SM2-SM3" */
++    1195,    /* "SM2ENC" */
+     1143,    /* "SM3" */
+     1134,    /* "SM4-CBC" */
+     1137,    /* "SM4-CFB" */
+@@ -2559,6 +2565,9 @@
+     1135,    /* "SM4-OFB" */
+      188,    /* "SMIME" */
+      167,    /* "SMIME-CAPS" */
++    1197,    /* "SMS4-CBC" */
++    1199,    /* "SMS4-CCM" */
++    1198,    /* "SMS4-GCM" */
+      100,    /* "SN" */
+     1006,    /* "SNILS" */
+       16,    /* "ST" */
+@@ -3473,7 +3482,7 @@
+     1093,    /* "x509ExtAdmission" */
+ };
+ 
+-#define NUM_LN 1188
++#define NUM_LN 1191
+ static const unsigned int ln_objs[NUM_LN] = {
+      363,    /* "AD Time Stamping" */
+      405,    /* "ANSI X9.62" */
+@@ -4607,9 +4616,9 @@
+     1142,    /* "sm-scheme" */
+     1172,    /* "sm2" */
+     1195,    /* "sm2Encryption" */
+-    1196,    /* "sm2-sm3" */   
+     1143,    /* "sm3" */
+     1144,    /* "sm3WithRSAEncryption" */
++    1196,    /* "sm3WithSM2Encryption" */
+     1134,    /* "sm4-cbc" */
+     1137,    /* "sm4-cfb" */
+     1136,    /* "sm4-cfb1" */
+@@ -4617,6 +4626,9 @@
+     1139,    /* "sm4-ctr" */
+     1133,    /* "sm4-ecb" */
+     1135,    /* "sm4-ofb" */
++    1197,    /* "sms4-cbc" */
++    1199,    /* "sms4-ccm" */
++    1198,    /* "sms4-gcm" */
+       16,    /* "stateOrProvinceName" */
+      660,    /* "streetAddress" */
+      498,    /* "subtreeMaximumQuality" */
+@@ -4665,7 +4677,7 @@
+      125,    /* "zlib compression" */
+ };
+ 
+-#define NUM_OBJ 1073
++#define NUM_OBJ 1076
+ static const unsigned int obj_objs[NUM_OBJ] = {
+        0,    /* OBJ_undef                        0 */
+      181,    /* OBJ_iso                          1 */
+@@ -5029,6 +5041,7 @@
+      634,    /* OBJ_setAttr_TokICCsig            2 23 42 3 3 5 1 */
+      635,    /* OBJ_setAttr_SecDevSig            2 23 42 3 3 5 2 */
+      436,    /* OBJ_ucl                          0 9 2342 19200300 */
++    1197,    /* OBJ_sms4_cbc                     1 2 156 10197 1 104 */
+      820,    /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */
+      819,    /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */
+      845,    /* OBJ_id_GostR3410_94_a            1 2 643 2 2 20 1 */
+@@ -5132,9 +5145,11 @@
+     1136,    /* OBJ_sm4_cfb1                     1 2 156 10197 1 104 5 */
+     1138,    /* OBJ_sm4_cfb8                     1 2 156 10197 1 104 6 */
+     1139,    /* OBJ_sm4_ctr                      1 2 156 10197 1 104 7 */
++    1198,    /* OBJ_sms4_gcm                     1 2 156 10197 1 104 8 */
++    1199,    /* OBJ_sms4_ccm                     1 2 156 10197 1 104 9 */
+     1172,    /* OBJ_sm2                          1 2 156 10197 1 301 */
+     1143,    /* OBJ_sm3                          1 2 156 10197 1 401 */
+-    1196,    /* OBJ_sm3WithSM2Encryption         1 2 156 10197 1 501*/
++    1196,    /* OBJ_sm3WithSM2Encryption         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 -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/objects/objects.txt openssl-1.1.1d/crypto/objects/objects.txt
+--- openssl-1.1.1d-no-sm4-gcm/crypto/objects/objects.txt	2021-10-15 17:04:01.630776681 +0800
++++ openssl-1.1.1d/crypto/objects/objects.txt	2021-12-02 11:09:09.497296562 +0800
+@@ -1510,7 +1510,7 @@
+ 
+ 
+ # Definitions for SM4 cipher
+-
++sm-scheme 104           : SMS4-CBC            : sms4-cbc
+ sm-scheme 104 1         : SM4-ECB             : sm4-ecb
+ sm-scheme 104 2         : SM4-CBC             : sm4-cbc
+ !Cname sm4-ofb128
+@@ -1520,6 +1520,8 @@
+ sm-scheme 104 5         : SM4-CFB1            : sm4-cfb1
+ sm-scheme 104 6         : SM4-CFB8            : sm4-cfb8
+ sm-scheme 104 7         : SM4-CTR             : sm4-ctr
++sm-scheme 104 8         : SMS4-GCM            : sms4-gcm
++sm-scheme 104 9         : SMS4-CCM            : sms4-ccm
+ 
+ # There is no OID that just denotes "HMAC" oddly enough...
+ 
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_mac.num openssl-1.1.1d/crypto/objects/obj_mac.num
+--- openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_mac.num	2021-10-15 17:04:01.629776682 +0800
++++ openssl-1.1.1d/crypto/objects/obj_mac.num	2021-12-02 11:09:09.497296562 +0800
+@@ -1192,5 +1192,8 @@
+ magma_mac		1192
+ hmacWithSHA512_224		1193
+ hmacWithSHA512_256		1194
+-sm2Encryption			1195
+-sm3WithSM2Encryption	1196
++sm2Encryption		1195
++sm3WithSM2Encryption		1196
++sms4_cbc		1197
++sms4_gcm		1198
++sms4_ccm		1199
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_xref.h openssl-1.1.1d/crypto/objects/obj_xref.h
+--- openssl-1.1.1d-no-sm4-gcm/crypto/objects/obj_xref.h	2021-10-15 17:04:01.629776682 +0800
++++ openssl-1.1.1d/crypto/objects/obj_xref.h	2021-12-02 11:09:09.497296562 +0800
+@@ -2,7 +2,7 @@
+  * WARNING: do not edit!
+  * Generated by objxref.pl
+  *
+- * Copyright 1998-2019 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1998-2021 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
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/rsa/rsa_pss.c openssl-1.1.1d/crypto/rsa/rsa_pss.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/rsa/rsa_pss.c	2021-10-15 17:04:01.634776681 +0800
++++ openssl-1.1.1d/crypto/rsa/rsa_pss.c	2021-12-02 11:09:09.497296562 +0800
+@@ -166,14 +166,12 @@
+     if (sLen == RSA_PSS_SALTLEN_DIGEST) {
+         sLen = hLen;
+     } else if (sLen < RSA_PSS_SALTLEN_MAX) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+         goto err;
+     }
+ 
+     MSBits = (keylen_bit - 1) & 0x7;
+     emLen = (keylen_bit+7)/8;
+     if (EM[0] & (0xFF << MSBits)) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID);
+         goto err;
+     }
+     if (MSBits == 0) {
+@@ -181,24 +179,20 @@
+         emLen--;
+     }
+     if (emLen < hLen + 2) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+         goto err;
+     }
+     if (sLen == RSA_PSS_SALTLEN_MAX) {
+         sLen = emLen - hLen - 2;
+     } else if (sLen > emLen - hLen - 2) { /* sLen can be small negative */
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+         goto err;
+     }
+     if (EM[emLen - 1] != 0xbc) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID);
+         goto err;
+     }
+     maskedDBLen = emLen - hLen - 1;
+     H = EM + maskedDBLen;
+     DB = OPENSSL_malloc(maskedDBLen);
+     if (DB == NULL) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE);
+         goto err;
+     }
+     if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0)
+@@ -209,11 +203,9 @@
+         DB[0] &= 0xFF >> (8 - MSBits);
+     for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ;
+     if (DB[i++] != 0x1) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED);
+         goto err;
+     }
+     if (sLen != RSA_PSS_SALTLEN_AUTO && (maskedDBLen - i) != sLen) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+         goto err;
+     }
+     if (!EVP_DigestInit_ex(ctx, Hash, NULL)
+@@ -227,7 +219,6 @@
+     if (!EVP_DigestFinal_ex(ctx, H_, NULL))
+         goto err;
+     if (memcmp(H_, H, hLen)) {
+-        RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE);
+         ret = 0;
+     } else {
+         ret = 1;
+@@ -385,7 +376,6 @@
+     } else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) {
+         sLen = RSA_PSS_SALTLEN_MAX;
+     } else if (sLen < RSA_PSS_SALTLEN_MAX) {
+-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED);
+         goto err;
+     }
+ 
+@@ -396,22 +386,16 @@
+         emLen--;
+     }
+     if (emLen < hLen + 2) {
+-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+-               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+         goto err;
+     }
+     if (sLen == RSA_PSS_SALTLEN_MAX) {
+         sLen = emLen - hLen - 2;
+     } else if (sLen > emLen - hLen - 2) {
+-        RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+-               RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+         goto err;
+     }
+     if (sLen > 0) {
+         salt = OPENSSL_malloc(sLen);
+         if (salt == NULL) {
+-            RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+-                   ERR_R_MALLOC_FAILURE);
+             goto err;
+         }
+         if (RAND_bytes(salt, sLen) <= 0)
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/sm4/build.info openssl-1.1.1d/crypto/sm4/build.info
+--- openssl-1.1.1d-no-sm4-gcm/crypto/sm4/build.info	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/crypto/sm4/build.info	2021-12-02 11:09:09.498296561 +0800
+@@ -1,4 +1,4 @@
+ LIBS=../../libcrypto
+ SOURCE[../../libcrypto]=\
+-        sm4.c
++        sm4.c sms4.c sms4_ssl.c
+ 
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/sm4/sms4.c openssl-1.1.1d/crypto/sm4/sms4.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/sm4/sms4.c	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/sm4/sms4.c	2021-12-02 11:09:09.498296561 +0800
+@@ -0,0 +1,290 @@
++/* crypto/sms4/sms4.c */
++/* ====================================================================
++ * Copyright (c) 2014 - 2015 The GmSSL Project.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in
++ *    the documentation and/or other materials provided with the
++ *    distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ *    software must display the following acknowledgment:
++ *    "This product includes software developed by the GmSSL Project.
++ *    (http://gmssl.org/)"
++ *
++ * 4. The name "GmSSL Project" must not be used to endorse or promote
++ *    products derived from this software without prior written
++ *    permission. For written permission, please contact
++ *    guanzhi1980@gmail.com.
++ *
++ * 5. Products derived from this software may not be called "GmSSL"
++ *    nor may "GmSSL" appear in their names without prior written
++ *    permission of the GmSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ *    acknowledgment:
++ *    "This product includes software developed by the GmSSL Project
++ *    (http://gmssl.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE GmSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ */
++
++#include <openssl/sms4.h>
++
++#define FK0	0xa3b1bac6
++#define FK1	0x56aa3350
++#define FK2	0x677d9197
++#define FK3	0xb27022dc
++
++#define CK0	0x00070e15
++#define CK1	0x1c232a31
++#define CK2	0x383f464d
++#define CK3	0x545b6269
++#define CK4	0x70777e85
++#define CK5	0x8c939aa1
++#define CK6	0xa8afb6bd
++#define CK7	0xc4cbd2d9 
++#define CK8	0xe0e7eef5
++#define CK9	0xfc030a11
++#define CK10	0x181f262d
++#define CK11	0x343b4249
++#define CK12	0x50575e65
++#define CK13	0x6c737a81
++#define CK14	0x888f969d
++#define CK15	0xa4abb2b9 
++#define CK16	0xc0c7ced5
++#define CK17	0xdce3eaf1
++#define CK18	0xf8ff060d
++#define CK19	0x141b2229
++#define CK20	0x30373e45
++#define CK21	0x4c535a61
++#define CK22	0x686f767d
++#define CK23	0x848b9299
++#define CK24	0xa0a7aeb5
++#define CK25	0xbcc3cad1
++#define CK26	0xd8dfe6ed
++#define CK27	0xf4fb0209
++#define CK28	0x10171e25
++#define CK29	0x2c333a41
++#define CK30	0x484f565d
++#define CK31	0x646b7279 
++
++static const uint8_t SBOX[256] = {
++	0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7,
++	0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
++	0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3,
++	0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
++	0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a,
++	0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
++	0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95,
++	0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
++	0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba,
++	0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
++	0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b,
++	0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
++	0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2,
++	0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
++	0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52,
++	0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
++	0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5,
++	0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
++	0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55,
++	0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
++	0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60,
++	0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
++	0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f,
++	0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
++	0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f,
++	0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
++	0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd,
++	0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
++	0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e,
++	0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
++	0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20,
++	0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48 
++};
++
++
++#define GETU32(pc)  ( \
++		((uint32_t)(pc)[0] << 24) ^ \
++		((uint32_t)(pc)[1] << 16) ^ \
++		((uint32_t)(pc)[2] <<  8) ^ \
++		((uint32_t)(pc)[3]))
++
++#define PUTU32(st, ct)  { \
++		(ct)[0] = (uint8_t)((st) >> 24); \
++		(ct)[1] = (uint8_t)((st) >> 16); \
++		(ct)[2] = (uint8_t)((st) >>  8); \
++		(ct)[3] = (uint8_t)(st); }
++
++
++#define ROT(A,i) (((A) << i) | ((A) >> (32 - i)))
++
++#define S(A)	((SBOX[((A) >> 24)       ] << 24) ^ \
++		 (SBOX[((A) >> 16) & 0xff] << 16) ^ \
++		 (SBOX[((A) >>  8) & 0xff] <<  8) ^ \
++		 (SBOX[((A))       & 0xff]))
++
++#define L(B)	((B) ^ ROT((B), 2) ^ ROT((B),10) ^ ROT((B),18) ^ ROT((B), 24))
++#define L_(B)	((B) ^ ROT((B),13) ^ ROT((B),23))
++
++#define ROUND(X0,X1,X2,X3,X4,RK)	X4=(X1)^(X2)^(X3)^(RK); X4=S(X4); X4=(X0)^L(X4)
++#define ROUND_(X0,X1,X2,X3,X4,CK,RK)	X4=(X1)^(X2)^(X3)^(CK); X4=S(X4); X4=(X0)^L_(X4); RK=X4
++
++void sms4_set_encrypt_key(sms4_key_t *key, const unsigned char *user_key)
++{
++	uint32_t *rk = key->rk;
++	uint32_t X0, X1, X2, X3, X4;
++
++	X0 = GETU32(user_key     ) ^ FK0;
++	X1 = GETU32(user_key  + 4) ^ FK1;
++	X2 = GETU32(user_key  + 8) ^ FK2;
++	X3 = GETU32(user_key + 12) ^ FK3;
++
++	ROUND_(X0, X1, X2, X3, X4, CK0,  rk[0]);
++	ROUND_(X1, X2, X3, X4, X0, CK1,  rk[1]);
++	ROUND_(X2, X3, X4, X0, X1, CK2,  rk[2]);
++	ROUND_(X3, X4, X0, X1, X2, CK3,  rk[3]);
++	ROUND_(X4, X0, X1, X2, X3, CK4,  rk[4]);
++	ROUND_(X0, X1, X2, X3, X4, CK5,  rk[5]);
++	ROUND_(X1, X2, X3, X4, X0, CK6,  rk[6]);
++	ROUND_(X2, X3, X4, X0, X1, CK7,  rk[7]);
++	ROUND_(X3, X4, X0, X1, X2, CK8,  rk[8]);
++	ROUND_(X4, X0, X1, X2, X3, CK9,  rk[9]);
++	ROUND_(X0, X1, X2, X3, X4, CK10, rk[10]);
++	ROUND_(X1, X2, X3, X4, X0, CK11, rk[11]);
++	ROUND_(X2, X3, X4, X0, X1, CK12, rk[12]);
++	ROUND_(X3, X4, X0, X1, X2, CK13, rk[13]);
++	ROUND_(X4, X0, X1, X2, X3, CK14, rk[14]);
++	ROUND_(X0, X1, X2, X3, X4, CK15, rk[15]);
++	ROUND_(X1, X2, X3, X4, X0, CK16, rk[16]);
++	ROUND_(X2, X3, X4, X0, X1, CK17, rk[17]);
++	ROUND_(X3, X4, X0, X1, X2, CK18, rk[18]);
++	ROUND_(X4, X0, X1, X2, X3, CK19, rk[19]);
++	ROUND_(X0, X1, X2, X3, X4, CK20, rk[20]);
++	ROUND_(X1, X2, X3, X4, X0, CK21, rk[21]);
++	ROUND_(X2, X3, X4, X0, X1, CK22, rk[22]);
++	ROUND_(X3, X4, X0, X1, X2, CK23, rk[23]);
++	ROUND_(X4, X0, X1, X2, X3, CK24, rk[24]);
++	ROUND_(X0, X1, X2, X3, X4, CK25, rk[25]);
++	ROUND_(X1, X2, X3, X4, X0, CK26, rk[26]);
++	ROUND_(X2, X3, X4, X0, X1, CK27, rk[27]);
++	ROUND_(X3, X4, X0, X1, X2, CK28, rk[28]);
++	ROUND_(X4, X0, X1, X2, X3, CK29, rk[29]);
++	ROUND_(X0, X1, X2, X3, X4, CK30, rk[30]);
++	ROUND_(X1, X2, X3, X4, X0, CK31, rk[31]);
++}
++
++void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char *user_key)
++{
++	uint32_t *rk = key->rk;
++	uint32_t X0, X1, X2, X3, X4;
++
++	X0 = GETU32(user_key     ) ^ FK0;
++	X1 = GETU32(user_key  + 4) ^ FK1;
++	X2 = GETU32(user_key  + 8) ^ FK2;
++	X3 = GETU32(user_key + 12) ^ FK3;
++
++	ROUND_(X0, X1, X2, X3, X4, CK0,  rk[31]);
++	ROUND_(X1, X2, X3, X4, X0, CK1,  rk[30]);
++	ROUND_(X2, X3, X4, X0, X1, CK2,  rk[29]);
++	ROUND_(X3, X4, X0, X1, X2, CK3,  rk[28]);
++	ROUND_(X4, X0, X1, X2, X3, CK4,  rk[27]);
++	ROUND_(X0, X1, X2, X3, X4, CK5,  rk[26]);
++	ROUND_(X1, X2, X3, X4, X0, CK6,  rk[25]);
++	ROUND_(X2, X3, X4, X0, X1, CK7,  rk[24]);
++	ROUND_(X3, X4, X0, X1, X2, CK8,  rk[23]);
++	ROUND_(X4, X0, X1, X2, X3, CK9,  rk[22]);
++	ROUND_(X0, X1, X2, X3, X4, CK10, rk[21]);
++	ROUND_(X1, X2, X3, X4, X0, CK11, rk[20]);
++	ROUND_(X2, X3, X4, X0, X1, CK12, rk[19]);
++	ROUND_(X3, X4, X0, X1, X2, CK13, rk[18]);
++	ROUND_(X4, X0, X1, X2, X3, CK14, rk[17]);
++	ROUND_(X0, X1, X2, X3, X4, CK15, rk[16]);
++	ROUND_(X1, X2, X3, X4, X0, CK16, rk[15]);
++	ROUND_(X2, X3, X4, X0, X1, CK17, rk[14]);
++	ROUND_(X3, X4, X0, X1, X2, CK18, rk[13]);
++	ROUND_(X4, X0, X1, X2, X3, CK19, rk[12]);
++	ROUND_(X0, X1, X2, X3, X4, CK20, rk[11]);
++	ROUND_(X1, X2, X3, X4, X0, CK21, rk[10]);
++	ROUND_(X2, X3, X4, X0, X1, CK22, rk[9]);
++	ROUND_(X3, X4, X0, X1, X2, CK23, rk[8]);
++	ROUND_(X4, X0, X1, X2, X3, CK24, rk[7]);
++	ROUND_(X0, X1, X2, X3, X4, CK25, rk[6]);
++	ROUND_(X1, X2, X3, X4, X0, CK26, rk[5]);
++	ROUND_(X2, X3, X4, X0, X1, CK27, rk[4]);
++	ROUND_(X3, X4, X0, X1, X2, CK28, rk[3]);
++	ROUND_(X4, X0, X1, X2, X3, CK29, rk[2]);
++	ROUND_(X0, X1, X2, X3, X4, CK30, rk[1]);
++	ROUND_(X1, X2, X3, X4, X0, CK31, rk[0]);
++}
++
++void sms4_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key)
++{
++	uint32_t *rk = key->rk;
++	uint32_t X0, X1, X2, X3, X4;
++
++	X0 = GETU32(in     );
++	X1 = GETU32(in +  4);
++	X2 = GETU32(in +  8);
++	X3 = GETU32(in + 12);
++
++	ROUND(X0, X1, X2, X3, X4, rk[0]);
++	ROUND(X1, X2, X3, X4, X0, rk[1]);
++	ROUND(X2, X3, X4, X0, X1, rk[2]);
++	ROUND(X3, X4, X0, X1, X2, rk[3]);
++	ROUND(X4, X0, X1, X2, X3, rk[4]);
++	ROUND(X0, X1, X2, X3, X4, rk[5]);
++	ROUND(X1, X2, X3, X4, X0, rk[6]);
++	ROUND(X2, X3, X4, X0, X1, rk[7]);
++	ROUND(X3, X4, X0, X1, X2, rk[8]);
++	ROUND(X4, X0, X1, X2, X3, rk[9]);
++	ROUND(X0, X1, X2, X3, X4, rk[10]);
++	ROUND(X1, X2, X3, X4, X0, rk[11]);
++	ROUND(X2, X3, X4, X0, X1, rk[12]);
++	ROUND(X3, X4, X0, X1, X2, rk[13]);
++	ROUND(X4, X0, X1, X2, X3, rk[14]);
++	ROUND(X0, X1, X2, X3, X4, rk[15]);
++	ROUND(X1, X2, X3, X4, X0, rk[16]);
++	ROUND(X2, X3, X4, X0, X1, rk[17]);
++	ROUND(X3, X4, X0, X1, X2, rk[18]);
++	ROUND(X4, X0, X1, X2, X3, rk[19]);
++	ROUND(X0, X1, X2, X3, X4, rk[20]);
++	ROUND(X1, X2, X3, X4, X0, rk[21]);
++	ROUND(X2, X3, X4, X0, X1, rk[22]);
++	ROUND(X3, X4, X0, X1, X2, rk[23]);
++	ROUND(X4, X0, X1, X2, X3, rk[24]);
++	ROUND(X0, X1, X2, X3, X4, rk[25]);
++	ROUND(X1, X2, X3, X4, X0, rk[26]);
++	ROUND(X2, X3, X4, X0, X1, rk[27]);
++	ROUND(X3, X4, X0, X1, X2, rk[28]);
++	ROUND(X4, X0, X1, X2, X3, rk[29]);
++	ROUND(X0, X1, X2, X3, X4, rk[30]);
++	ROUND(X1, X2, X3, X4, X0, rk[31]);
++
++	PUTU32(X0, out);
++	PUTU32(X4, out + 4);
++	PUTU32(X3, out + 8);
++	PUTU32(X2, out + 12);
++}
++
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/crypto/sm4/sms4_ssl.c openssl-1.1.1d/crypto/sm4/sms4_ssl.c
+--- openssl-1.1.1d-no-sm4-gcm/crypto/sm4/sms4_ssl.c	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/crypto/sm4/sms4_ssl.c	2021-12-02 11:18:32.093266195 +0800
+@@ -0,0 +1,202 @@
++#include <stdio.h>
++#include <stdlib.h>
++#include <errno.h>
++#include <string.h>
++#include <openssl/bio.h>
++#include <openssl/evp.h>
++#include <openssl/err.h>
++#include <openssl/ssl.h>
++#include "openssl/sms4_ssl.h"
++
++#if 0
++#define PRINTF(label, buf, len) do { \
++   int ivenky;                                 \
++   printf("%s. %s [%d bytes]:\n", __FUNCTION__, (label), (len));        \
++   for (ivenky = 0; ivenky < (len); ivenky++) {\
++      printf("0x%02x%s", (buf)[ivenky],  (ivenky % 8 == 7) ? "\n" : ", ");	\
++   }\
++   printf("\n"); \
++} while (0)
++#define ssl_dbg_printf(format, args...) printf(format, ## args)
++#else
++#define PRINTF(label, buf, len)
++#define ssl_dbg_printf(format, args...)
++#endif
++
++static BIO *bio_s_out = NULL;
++
++// ivlen -> [7, 13]
++// taglen -> [4, 16], can't be odd
++int openssl_sms4_ccm_encrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen)
++{
++    int ret = 0;
++    int outlen = 0;
++    EVP_CIPHER_CTX *ctx = NULL;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if(ctx == NULL)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_CIPHER_CTX_new failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    ret = EVP_EncryptInit_ex(ctx, EVP_sms4_ccm(), NULL, NULL, NULL);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_EncryptInit_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL);
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL);
++
++    EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
++    if(ad != NULL && adlen > 0)
++    {
++        EVP_EncryptUpdate(ctx, NULL, &outlen, NULL, len);
++        EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adlen);
++    }
++    EVP_EncryptUpdate(ctx, dst, &outlen, src, len);
++
++    ret = EVP_EncryptFinal_ex(ctx, dst, &outlen);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_EncryptFinal_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag);
++
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 1;
++ErrP:
++    ERR_print_errors_fp(stderr);
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 0;
++}
++
++// ivlen -> [7, 13]
++// taglen -> [4, 16], can't be odd
++int openssl_sms4_ccm_decrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen)
++{
++    int ret = 0;
++    int outlen = 0;
++    EVP_CIPHER_CTX *ctx = NULL;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if(ctx == NULL)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_CIPHER_CTX_new failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    ret = EVP_DecryptInit_ex(ctx, EVP_sms4_ccm(), NULL, NULL, NULL);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_DecryptInit_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL);
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, tag);
++
++    EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv);
++    if(ad != NULL && adlen > 0)
++    {
++        EVP_DecryptUpdate(ctx, NULL, &outlen, NULL, len);
++        EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adlen);
++    }
++
++    ret = EVP_DecryptUpdate(ctx, dst, &outlen, src, len);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_DecryptUpdate failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 1;
++ErrP:
++    ERR_print_errors_fp(stderr);
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 0;
++}
++
++int openssl_sms4_gcm_encrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen)
++{
++    int ret = 0;
++    int outlen = 0;
++    EVP_CIPHER_CTX *ctx = NULL;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if(ctx == NULL)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_CIPHER_CTX_new failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    ret = EVP_EncryptInit_ex(ctx, EVP_sms4_gcm(), NULL, NULL, NULL);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_EncryptInit_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL);
++
++    EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv);
++    if(ad != NULL && adlen > 0) EVP_EncryptUpdate(ctx, NULL, &outlen, ad, adlen);
++    EVP_EncryptUpdate(ctx, dst, &outlen, src, len);
++
++    ret = EVP_EncryptFinal_ex(ctx, dst, &outlen);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_EncryptFinal_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag);
++
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 0;
++ErrP:
++    ERR_print_errors_fp(stderr);
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return -1;
++}
++
++int openssl_sms4_gcm_decrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen)
++{
++    int ret = 0;
++    int outlen = 0;
++    EVP_CIPHER_CTX *ctx = NULL;
++
++    ctx = EVP_CIPHER_CTX_new();
++    if(ctx == NULL)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_CIPHER_CTX_new failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    ret = EVP_DecryptInit_ex(ctx, EVP_sms4_gcm(), NULL, NULL, NULL);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_DecryptInit_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL);
++
++    EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv);
++    if(ad != NULL && adlen > 0) EVP_DecryptUpdate(ctx, NULL, &outlen, ad, adlen);
++    EVP_DecryptUpdate(ctx, dst, &outlen, src, len);
++
++    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, taglen, tag);
++    ret = EVP_DecryptFinal_ex(ctx, dst, &outlen);
++    if(ret <= 0)
++    {
++        fprintf(stderr, "%s %s:%u - EVP_DecryptFinal_ex failed\n", __FUNCTION__, __FILE__, __LINE__);
++        goto ErrP;
++    }
++
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return 0;
++ErrP:
++    ERR_print_errors_fp(stderr);
++    if(ctx) EVP_CIPHER_CTX_free(ctx);
++    return -1;
++}
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/fuzz/oids.txt openssl-1.1.1d/fuzz/oids.txt
+--- openssl-1.1.1d-no-sm4-gcm/fuzz/oids.txt	2019-09-10 21:13:07.000000000 +0800
++++ openssl-1.1.1d/fuzz/oids.txt	2021-12-02 11:09:09.498296561 +0800
+@@ -1063,3 +1063,8 @@
+ 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_sm2Encryption="\x2A\x81\x1C\xCF\x55\x01\x82\x2D\x01"
++OBJ_sm3WithSM2Encryption="\x2A\x81\x1C\xCF\x55\x01\x83\x75"
++OBJ_sms4_cbc="\x2A\x81\x1C\xCF\x55\x01\x68"
++OBJ_sms4_gcm="\x2A\x81\x1C\xCF\x55\x01\x68\x08"
++OBJ_sms4_ccm="\x2A\x81\x1C\xCF\x55\x01\x68\x09"
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/include/openssl/evp.h openssl-1.1.1d/include/openssl/evp.h
+--- openssl-1.1.1d-no-sm4-gcm/include/openssl/evp.h	2021-10-15 17:04:01.631776681 +0800
++++ openssl-1.1.1d/include/openssl/evp.h	2021-12-02 11:09:09.499296561 +0800
+@@ -233,6 +233,13 @@
+                                                           int type, int arg,
+                                                           void *ptr);
+ 
++/* Macros to code block cipher wrappers */
++
++/* Wrapper functions for each cipher mode */
++
++#define EVP_C_DATA(kstruct, ctx) \
++        ((kstruct *)EVP_CIPHER_CTX_get_cipher_data(ctx))
++
+ /* Values for cipher flags */
+ 
+ /* Modes for ciphers */
+@@ -947,6 +954,10 @@
+ #  define EVP_sm4_cfb EVP_sm4_cfb128
+ const EVP_CIPHER *EVP_sm4_ofb(void);
+ const EVP_CIPHER *EVP_sm4_ctr(void);
++
++const EVP_CIPHER *EVP_sms4(void);
++const EVP_CIPHER *EVP_sms4_gcm(void);
++const EVP_CIPHER *EVP_sms4_ccm(void);
+ # endif
+ 
+ # if OPENSSL_API_COMPAT < 0x10100000L
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/include/openssl/obj_mac.h openssl-1.1.1d/include/openssl/obj_mac.h
+--- openssl-1.1.1d-no-sm4-gcm/include/openssl/obj_mac.h	2021-10-15 17:04:01.632776681 +0800
++++ openssl-1.1.1d/include/openssl/obj_mac.h	2021-12-02 11:09:09.499296561 +0800
+@@ -2,7 +2,7 @@
+  * WARNING: do not edit!
+  * Generated by crypto/objects/objects.pl
+  *
+- * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 2000-2021 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
+  * in the file LICENSE in the source distribution or at
+@@ -1169,26 +1169,26 @@
+ #define NID_sm2         1172
+ #define OBJ_sm2         OBJ_sm_scheme,301L
+ 
+-#define SN_sm3          "SM3"
+-#define LN_sm3          "sm3"
+-#define NID_sm3         1143
+-#define OBJ_sm3         OBJ_sm_scheme,401L
+-
+ #define SN_sm2Encryption                "SM2ENC"
+ #define LN_sm2Encryption                "sm2Encryption"
+ #define NID_sm2Encryption               1195
+-#define OBJ_sm2Encryption               1L,2L,156L,10197L,1L,301L,1L
++#define OBJ_sm2Encryption               OBJ_sm_scheme,301L,1L
+ 
+-#define SN_sm3WithSM2Encryption         "SM2-SM3"
+-#define LN_sm3WithSM2Encryption         "sm3WithSM2Encryption"
+-#define NID_sm3WithSM2Encryption                1196
+-#define OBJ_sm3WithSM2Encryption                1L,2L,156L,10197L,1L,501L
++#define SN_sm3          "SM3"
++#define LN_sm3          "sm3"
++#define NID_sm3         1143
++#define OBJ_sm3         OBJ_sm_scheme,401L
+ 
+ #define SN_sm3WithRSAEncryption         "RSA-SM3"
+ #define LN_sm3WithRSAEncryption         "sm3WithRSAEncryption"
+ #define NID_sm3WithRSAEncryption                1144
+ #define OBJ_sm3WithRSAEncryption                OBJ_sm_scheme,504L
+ 
++#define SN_sm3WithSM2Encryption         "SM2-SM3"
++#define LN_sm3WithSM2Encryption         "sm3WithSM2Encryption"
++#define NID_sm3WithSM2Encryption                1196
++#define OBJ_sm3WithSM2Encryption                OBJ_sm_scheme,501L
++
+ #define LN_hmacWithSHA224               "hmacWithSHA224"
+ #define NID_hmacWithSHA224              798
+ #define OBJ_hmacWithSHA224              OBJ_rsadsi,2L,8L
+@@ -4742,6 +4742,11 @@
+ #define NID_seed_ofb128         778
+ #define OBJ_seed_ofb128         OBJ_kisa,1L,6L
+ 
++#define SN_sms4_cbc             "SMS4-CBC"
++#define LN_sms4_cbc             "sms4-cbc"
++#define NID_sms4_cbc            1197
++#define OBJ_sms4_cbc            OBJ_sm_scheme,104L
++
+ #define SN_sm4_ecb              "SM4-ECB"
+ #define LN_sm4_ecb              "sm4-ecb"
+ #define NID_sm4_ecb             1133
+@@ -4777,6 +4782,16 @@
+ #define NID_sm4_ctr             1139
+ #define OBJ_sm4_ctr             OBJ_sm_scheme,104L,7L
+ 
++#define SN_sms4_gcm             "SMS4-GCM"
++#define LN_sms4_gcm             "sms4-gcm"
++#define NID_sms4_gcm            1198
++#define OBJ_sms4_gcm            OBJ_sm_scheme,104L,8L
++
++#define SN_sms4_ccm             "SMS4-CCM"
++#define LN_sms4_ccm             "sms4-ccm"
++#define NID_sms4_ccm            1199
++#define OBJ_sms4_ccm            OBJ_sm_scheme,104L,9L
++
+ #define SN_hmac         "HMAC"
+ #define LN_hmac         "hmac"
+ #define NID_hmac                855
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/include/openssl/sms4.h openssl-1.1.1d/include/openssl/sms4.h
+--- openssl-1.1.1d-no-sm4-gcm/include/openssl/sms4.h	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/include/openssl/sms4.h	2021-12-02 11:09:09.500296561 +0800
+@@ -0,0 +1,83 @@
++/* crypto/sms4/sms4.h */
++/* ====================================================================
++ * Copyright (c) 2014 - 2015 The GmSSL Project.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ *
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in
++ *    the documentation and/or other materials provided with the
++ *    distribution.
++ *
++ * 3. All advertising materials mentioning features or use of this
++ *    software must display the following acknowledgment:
++ *    "This product includes software developed by the GmSSL Project.
++ *    (http://gmssl.org/)"
++ *
++ * 4. The name "GmSSL Project" must not be used to endorse or promote
++ *    products derived from this software without prior written
++ *    permission. For written permission, please contact
++ *    guanzhi1980@gmail.com.
++ *
++ * 5. Products derived from this software may not be called "GmSSL"
++ *    nor may "GmSSL" appear in their names without prior written
++ *    permission of the GmSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ *    acknowledgment:
++ *    "This product includes software developed by the GmSSL Project
++ *    (http://gmssl.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE GmSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ */
++
++#ifndef HEADER_SMS4_H
++#define HEADER_SMS4_H
++
++#define SMS4_KEY_LENGTH		16
++#define SMS4_BLOCK_SIZE		16
++#define SMS4_NUM_ROUNDS		32
++
++#include <sys/types.h>
++#include <stdint.h>
++#include <string.h>
++#include "openssl/modes.h"
++
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++typedef struct {
++	uint32_t rk[SMS4_NUM_ROUNDS];
++} sms4_key_t;
++
++void sms4_set_encrypt_key(sms4_key_t *key, const unsigned char *user_key);
++void sms4_set_decrypt_key(sms4_key_t *key, const unsigned char *user_key);
++
++void sms4_encrypt(const unsigned char *in, unsigned char *out, sms4_key_t *key);
++#define sms4_decrypt(in,out,key)  sms4_encrypt(in,out,key)
++
++#ifdef __cplusplus
++}
++#endif
++#endif
++
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/include/openssl/sms4_ssl.h openssl-1.1.1d/include/openssl/sms4_ssl.h
+--- openssl-1.1.1d-no-sm4-gcm/include/openssl/sms4_ssl.h	1970-01-01 08:00:00.000000000 +0800
++++ openssl-1.1.1d/include/openssl/sms4_ssl.h	2021-12-02 11:09:09.500296561 +0800
+@@ -0,0 +1,28 @@
++#ifndef __SMS4_SSL_H__
++#define __SMS4_SSL_H__
++
++// adlen -> [0, ...]
++// ivlen -> [7, 13]
++// taglen -> [4, 16], can't be odd
++int openssl_sms4_ccm_encrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen);
++
++// adlen -> [0, ...]
++// ivlen -> [7, 13]
++// taglen -> [4, 16], can't be odd
++int openssl_sms4_ccm_decrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen);
++
++// adlen -> [0, ...]
++// ivlen -> [1, ...]
++// taglen -> [1, 16]
++int openssl_sms4_gcm_encrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen);
++
++// adlen -> [0, ...]
++// ivlen -> [1, ...]
++// taglen -> [1, 16]
++int openssl_sms4_gcm_decrypt(unsigned char *src, unsigned char *dst, int len, unsigned char *key, unsigned char *iv, int ivlen, unsigned char *ad, int adlen, unsigned char *tag, int taglen);
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif
+diff -urNa -r -r openssl-1.1.1d-no-sm4-gcm/util/libcrypto.num openssl-1.1.1d/util/libcrypto.num
+--- openssl-1.1.1d-no-sm4-gcm/util/libcrypto.num	2021-10-15 17:04:01.648776681 +0800
++++ openssl-1.1.1d/util/libcrypto.num	2021-12-02 11:09:09.500296561 +0800
+@@ -4582,10 +4582,20 @@
+ EVP_PKEY_get0_engine                    4536	1_1_1c	EXIST::FUNCTION:ENGINE
+ X509_get0_authority_serial              4537	1_1_1d	EXIST::FUNCTION:
+ X509_get0_authority_issuer              4538	1_1_1d	EXIST::FUNCTION:
+-X509_NAME_print_ex_for_certm            4539    1_1_1d  EXIST::FUNCTION:
+-array_sm2_decrypt                       4540    1_1_1d  EXIST::FUNCTION:SM2
+-sms4_set_key                            4541    1_1_1d  EXIST::FUNCTION:SM4
+-sms4_ecb_decrypt                        4542    1_1_1d  EXIST::FUNCTION:SM4
+-Array_RSA_verify_PKCS1_PSS_mgf1         4543    1_1_1d  EXIST::FUNCTION:RSA
+-Array_RSA_padding_add_PKCS1_PSS_mgf1    4544    1_1_1d  EXIST::FUNCTION:RSA
+-array_sm2_do_verify                     4545    1_1_1d  EXIST::FUNCTION:SM2
++X509_NAME_print_ex_for_certm            4539	1_1_1d	EXIST::FUNCTION:STDIO
++array_sm2_decrypt                       4540	1_1_1d	EXIST::FUNCTION:SM2
++sms4_set_key                            4541	1_1_1d	EXIST::FUNCTION:SM4
++sms4_ecb_decrypt                        4542	1_1_1d	EXIST::FUNCTION:SM4
++Array_RSA_verify_PKCS1_PSS_mgf1         4543	1_1_1d	EXIST::FUNCTION:RSA
++Array_RSA_padding_add_PKCS1_PSS_mgf1    4544	1_1_1d	EXIST::FUNCTION:RSA
++array_sm2_do_verify                     4545	1_1_1d	EXIST::FUNCTION:SM2
++openssl_sms4_ccm_decrypt                4546	1_1_1d	EXIST::FUNCTION:
++openssl_sms4_gcm_decrypt                4547	1_1_1d	EXIST::FUNCTION:
++openssl_sms4_gcm_encrypt                4548	1_1_1d	EXIST::FUNCTION:
++sms4_set_encrypt_key                    4549	1_1_1d	EXIST::FUNCTION:
++sms4_encrypt                            4550	1_1_1d	EXIST::FUNCTION:
++openssl_sms4_ccm_encrypt                4551	1_1_1d	EXIST::FUNCTION:
++sms4_set_decrypt_key                    4552	1_1_1d	EXIST::FUNCTION:
++EVP_sms4_gcm                            4553	1_1_1d	EXIST::FUNCTION:SM4
++EVP_sms4_ccm                            4554	1_1_1d	EXIST::FUNCTION:SM4
++EVP_sms4                                4555	1_1_1d	EXIST::FUNCTION:SM4
Index: /branches/rel_ag_9_4_5/ssl-111/install_perl5.10.1.sh
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/install_perl5.10.1.sh	(revision 0)
+++ /branches/rel_ag_9_4_5/ssl-111/install_perl5.10.1.sh	(working copy)
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+PERL_BIN="/usr/local/bin/perl5.10.1"
+
+if [ -x "$PERL_BIN" ]; then
+    echo "Perl 5.10.1  already exists at $PERL_BIN"
+    exit 0
+fi
+
+echo "Perl 5.10.1 not found. Installing Perl 5.10.1..."
+
+tar -xzf perl-5.10.1.tar.gz
+cd perl-5.10.1
+
+./Configure -des -Dprefix=/usr/local/perl5.10.1
+
+make || { echo "Make failed"; exit 1; }
+make install || { echo "Make install failed"; exit 1; }
+
+ln -sf "/usr/local/perl5.10.1/bin/perl" "$PERL_BIN" || { echo "Failed to create symlink"; exit 1; }
+
+echo "Perl 5.10.1 installed successfully"
\ No newline at end of file
Index: /branches/rel_ag_9_4_5/ssl-111/openssl-1.1.1d.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-gzip
Index: /branches/rel_ag_9_4_5/ssl-111/openssl-1.1.1d.tar.gz
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/openssl-1.1.1d.tar.gz	(revision 20526)
+++ /branches/rel_ag_9_4_5/ssl-111/openssl-1.1.1d.tar.gz	(working copy)

Property changes on: ssl-111/openssl-1.1.1d.tar.gz
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/x-gzip
\ No newline at end of property
Index: /branches/rel_ag_9_4_5/ssl-111/perl-5.10.1.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-gzip
Index: /branches/rel_ag_9_4_5/ssl-111/perl-5.10.1.tar.gz
===================================================================
--- /branches/rel_ag_9_4_5/ssl-111/perl-5.10.1.tar.gz	(revision 20526)
+++ /branches/rel_ag_9_4_5/ssl-111/perl-5.10.1.tar.gz	(working copy)

Property changes on: ssl-111/perl-5.10.1.tar.gz
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/x-gzip
\ No newline at end of property
