Supports sm2 algorithm signature and uses sm3 hash algorithm

This commit is contained in:
zhengxiaoxiao 2024-10-26 18:01:58 +08:00
parent 0534a8aea1
commit 2217f49b17
2 changed files with 554 additions and 5 deletions

View File

@ -1,6 +1,6 @@
Name: gnupg2
Version: 2.4.3
Release: 4
Release: 5
Summary: Utility for secure communication and data storage
License: GPLv3+
@ -20,17 +20,18 @@ Patch9: gnupg2-revert-rfc4880bis.patch
Patch10: backport-dirmngr-Enable-the-call-of-ks_ldap_help_variables-wh.patch
Patch11: backport-gpg-Make-no-literal-work-again-for-c-and-store.patch
Patch12: backport-gpg-Fix-minor-memory-leak-during-certain-smartcard-o.patch
Patch13: supports-sm2-algorithm-signature-and-uses-sm3-hash-algorithm.patch
BuildRequires: gcc
BuildRequires: zlib-devel, npth-devel, texinfo
BuildRequires: libgpg-error-devel >= 1.46
BuildRequires: libgcrypt-devel >= 1.9.4
BuildRequires: libgcrypt-devel >= 1.10.2-3
BuildRequires: libksba-devel >= 1.6.3
BuildRequires: libassuan-devel >= 2.5.0
# compile dirmngr module, need gnutls
BuildRequires: gnutls-devel
BuildRequires: gnutls-devel gettext-devel
Requires: libgcrypt >= 1.9.4
Requires: libgcrypt >= 1.10.2-3
Requires: libgpg-error >= 1.46
Recommends: pinentry
@ -59,6 +60,7 @@ signing to the base GnuPG package.
%prep
%autosetup -n gnupg-%{version} -p1
autoreconf -f
%global pcsclib %(basename $(ls -1 %{_libdir}/libpcsclite.so.? 2>/dev/null ) 2>/dev/null )
@ -72,7 +74,8 @@ sed -i -e 's/"libpcsclite\.so"/"%{pcsclib}"/' scd/scdaemon.c
--enable-g13 \
--disable-ccid-driver \
--disable-tpm2d \
--enable-large-secmem
--enable-large-secmem \
--enable-sm2
%make_build
@ -121,6 +124,9 @@ make check
%changelog
* Sat Oct 26 2024 zhengxiaoxiao <zhengxiaoxiao2@huawei.com> - 2.4.3-5
- Supports sm2 algorithm signature and uses sm3 hash algorithm.
* Mon Sep 30 2024 yixiangzhike <yixiangzhike007@163.com> - 2.4.3-4
- backport upstream patch to fix minor memory leak

View File

@ -0,0 +1,543 @@
From 12689a050972bc6a07c0b8dfdd379c50087b614b Mon Sep 17 00:00:00 2001
From: zhengxiaoxiao <zhengxiaoxiao2@huawei.com>
Date: Sat, 26 Oct 2024 16:59:41 +0800
Subject: [PATCH] Supports sm2 algorithm signature and uses sm3 hash algorithm.
Co-authored-by: Huaxin Lu <luhuaxin1@huawei.com>
Signed-off-by: zhengxiaoxiao <zhengxiaoxiao2@huawei.com>
---
agent/pksign.c | 25 +++++++-
common/Makefile.am | 3 +
common/openpgp-oid.c | 31 +++++++++
common/openpgpdefs.h | 4 ++
common/sm2.c | 149 +++++++++++++++++++++++++++++++++++++++++++
common/sm2.h | 24 +++++++
common/util.h | 3 +
configure.ac | 10 +++
g10/keygen.c | 3 +
g10/misc.c | 13 +++-
g10/pkglue.c | 5 ++
g10/sig-check.c | 12 ++++
g10/sign.c | 16 ++++-
sm/gpgsm.c | 3 +
14 files changed, 295 insertions(+), 6 deletions(-)
create mode 100644 common/sm2.c
create mode 100644 common/sm2.h
diff --git a/agent/pksign.c b/agent/pksign.c
index a7b5c57..249bcd9 100644
--- a/agent/pksign.c
+++ b/agent/pksign.c
@@ -28,7 +28,9 @@
#include "agent.h"
#include "../common/i18n.h"
-
+#ifdef GPG_USE_SM2
+#include "../common/sm2.h"
+#endif
static int
do_encode_md (const byte * md, size_t mdlen, int algo, gcry_sexp_t * r_hash,
@@ -209,7 +211,14 @@ do_encode_dsa (const byte *md, size_t mdlen, int pkalgo, gcry_sexp_t pkey,
mdlen = qbits/8;
/* Create the S-expression. */
- err = gcry_sexp_build (&hash, NULL,
+#ifdef GPG_USE_SM2
+ if (pkey_is_sm2(pkey))
+ err = gcry_sexp_build (&hash, NULL,
+ "(data (flags sm2) (hash %s %b))",
+ "sm3", (int)mdlen, md);
+ else
+#endif
+ err = gcry_sexp_build (&hash, NULL,
"(data (flags rfc6979) (hash %s %b))",
rfc6979_hash_algo_string (mdlen),
(int)mdlen, md);
@@ -494,6 +503,18 @@ agent_pksign_do (ctrl_t ctrl, const char *cache_nonce,
{
/* No smartcard, but a private key (in S_SKEY). */
+#ifdef GPG_USE_SM2
+ /* calculate sm2 digest */
+ if (pkey_is_sm2(s_skey))
+ {
+ if (!s_pkey)
+ agent_public_key_from_file (ctrl, ctrl->keygrip, &s_pkey);
+
+ err = update_sm2_hash_value (data, datalen, s_pkey, data);
+ if (err)
+ goto leave;
+ }
+#endif
/* Put the hash into a sexp */
if (algo == GCRY_PK_EDDSA)
err = do_encode_eddsa (gcry_pk_get_nbits (s_skey), data, datalen,
diff --git a/common/Makefile.am b/common/Makefile.am
index d5ab038..5e7ac35 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -99,6 +99,9 @@ common_sources = \
compliance.c compliance.h \
pkscreening.c pkscreening.h
+if GPG_USE_SM2
+common_sources += sm2.c sm2.h
+endif
if HAVE_W32_SYSTEM
common_sources += w32-reg.c w32-cmdline.c
diff --git a/common/openpgp-oid.c b/common/openpgp-oid.c
index 4930549..767a4e5 100644
--- a/common/openpgp-oid.c
+++ b/common/openpgp-oid.c
@@ -62,6 +62,9 @@ static struct {
{ "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", 512 },
{ "secp256k1", "1.3.132.0.10", 256 },
+#ifdef GPG_USE_SM2
+ { "sm2p256v1", "1.2.156.10197.1.301", 256 },
+#endif
{ NULL, NULL, 0}
};
@@ -92,6 +95,10 @@ static const char oid_cv448[] = { 0x03, 0x2b, 0x65, 0x6f };
/* The OID for Ed448 in OpenPGP format. */
static const char oid_ed448[] = { 0x03, 0x2b, 0x65, 0x71 };
+#ifdef GPG_USE_SM2
+/* The OID for SM2 in OpenPGP format. */
+static const char oid_sm2[] = { 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01, 0x82, 0x2d };
+#endif
/* A table to store keyalgo strings like "rsa2048 or "ed25519" so that
* we do not need to allocate them. This is currently a simple array
@@ -381,6 +388,15 @@ openpgp_oidbuf_is_cv448 (const void *buf, size_t len)
&& !memcmp (buf, oid_cv448, DIM (oid_cv448)));
}
+#ifdef GPG_USE_SM2
+/* Return true if (BUF,LEN) represents the OID for SM2. */
+static int
+openpgp_oidbuf_is_sm2 (const void *buf, size_t len)
+{
+ return (buf && len == DIM (oid_sm2)
+ && !memcmp (buf, oid_sm2, DIM (oid_sm2)));
+}
+#endif
/* Return true if the MPI A represents the OID for Curve25519. */
int
@@ -426,6 +442,21 @@ openpgp_oid_is_cv448 (gcry_mpi_t a)
return openpgp_oidbuf_is_cv448 (buf, (nbits+7)/8);
}
+#ifdef GPG_USE_SM2
+/* Return true if the MPI A represents the OID for SM2. */
+int
+openpgp_oid_is_sm2 (gcry_mpi_t a)
+{
+ const unsigned char *buf;
+ unsigned int nbits;
+
+ if (!a || !gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+ return 0;
+
+ buf = gcry_mpi_get_opaque (a, &nbits);
+ return openpgp_oidbuf_is_sm2 (buf, (nbits+7)/8);
+}
+#endif
/* Map the Libgcrypt ECC curve NAME to an OID. If R_NBITS is not NULL
store the bit size of the curve there. Returns NULL for unknown
diff --git a/common/openpgpdefs.h b/common/openpgpdefs.h
index 6257479..fd7e668 100644
--- a/common/openpgpdefs.h
+++ b/common/openpgpdefs.h
@@ -184,6 +184,10 @@ typedef enum
DIGEST_ALGO_SHA384 = 9,
DIGEST_ALGO_SHA512 = 10,
DIGEST_ALGO_SHA224 = 11,
+#ifdef GPG_USE_SM2
+ /* 100-110 Private or Experimental Use */
+ DIGEST_ALGO_SM3 = 109,
+#endif
DIGEST_ALGO_PRIVATE10 = 110
}
digest_algo_t;
diff --git a/common/sm2.c b/common/sm2.c
new file mode 100644
index 0000000..2d34dbb
--- /dev/null
+++ b/common/sm2.c
@@ -0,0 +1,149 @@
+/* openpgp-oids.c - OID helper for OpenPGP
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of either
+ *
+ * - the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * or
+ *
+ * - the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * or both in parallel, as here.
+ *
+ * This file is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "sm2.h"
+
+const unsigned char zin_default[] = {
+ 0x00, 0x80, // id length
+ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38, // default id: 1234567812345678
+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, // sm2 a
+ 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b,
+ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92,
+ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93, // sm2 b
+ 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46,
+ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1,
+ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7, // sm2 x
+ 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3,
+ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40,
+ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0 // sm2 y
+};
+
+static gpg_error_t
+calculate_za (gcry_mpi_t pkey, unsigned char *result)
+{
+ gpg_error_t err;
+ gcry_md_hd_t md;
+ unsigned char q[65];
+ size_t qlen;
+
+ err = gcry_mpi_print (GCRYMPI_FMT_STD, q, sizeof(q), &qlen, pkey);
+ if (err)
+ return err;
+
+ err = gcry_md_open (&md, GCRY_MD_SM3_PGP, 0);
+ if (err)
+ return err;
+
+ gcry_md_write (md, zin_default, sizeof(zin_default));
+ gcry_md_write (md, q + 1, qlen - 1);
+ gcry_md_final (md);
+ memcpy (result, gcry_md_read (md, GCRY_MD_SM3_PGP), 32);
+ gcry_md_close (md);
+
+ return 0;
+}
+
+gpg_error_t
+update_sm2_hash_md (gcry_md_hd_t md, gcry_mpi_t pkey)
+{
+ gpg_error_t err;
+ unsigned char za[32];
+ unsigned char msg[32];
+
+ if (!md || !pkey)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ err = calculate_za(pkey, za);
+ if (err)
+ return err;
+
+ memcpy(msg, gcry_md_read(md, GCRY_MD_SM3_PGP), 32);
+ gcry_md_reset(md);
+ gcry_md_write(md, za, sizeof(za));
+ gcry_md_write(md, msg, sizeof(msg));
+ gcry_md_final(md);
+
+ return 0;
+}
+
+gpg_error_t
+update_sm2_hash_value (unsigned char *msg, size_t msglen, gcry_sexp_t s_pkey, unsigned char *result)
+{
+ gpg_error_t err;
+ gcry_sexp_t q_sexp;
+ gcry_mpi_t q_mpi;
+ gcry_md_hd_t md;
+ unsigned char za[32];
+
+ if(!msg || !s_pkey || !result)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ q_sexp = gcry_sexp_find_token(s_pkey, "q", 0);
+ if (!q_sexp)
+ return gpg_error (GPG_ERR_NO_PUBKEY);
+
+ q_mpi = gcry_sexp_nth_mpi (q_sexp, 1, GCRYMPI_FMT_USG);
+ gcry_sexp_release (q_sexp);
+ if (!q_mpi)
+ return gpg_error (GPG_ERR_NO_PUBKEY);
+
+ err = calculate_za (q_mpi, za);
+ gcry_mpi_release (q_mpi);
+ if (err)
+ return err;
+
+ err = gcry_md_open (&md, GCRY_MD_SM3_PGP, 0);
+ if (err)
+ return err;
+
+ gcry_md_write (md, za, sizeof(za));
+ gcry_md_write (md, msg, msglen);
+ gcry_md_final (md);
+ memcpy (result, gcry_md_read (md, GCRY_MD_SM3_PGP), 32);
+ gcry_md_close (md);
+
+ return 0;
+}
+
+int pkey_is_sm2 (gcry_sexp_t pkey)
+{
+ const char *curve;
+
+ if (!pkey)
+ return 0;
+
+ curve = gcry_pk_get_curve (pkey, 0, NULL);
+ if (curve && !strcmp (curve, "sm2p256v1"))
+ return 1;
+
+ return 0;
+}
diff --git a/common/sm2.h b/common/sm2.h
new file mode 100644
index 0000000..7cd38d4
--- /dev/null
+++ b/common/sm2.h
@@ -0,0 +1,24 @@
+/* sm2.h
+ * Copyright (C) 2024 Free Software Foundation, Inc.
+ *
+ * This file is free software; as a special exception the author gives
+ * unlimited permission to copy and/or distribute it, with or without
+ * modifications, as long as this notice is preserved.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY, to the extent permitted by law; without even
+ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef GNUPG_COMMON_SM2_H
+#define GNUPG_COMMON_SM2_H
+
+#include <gcrypt.h>
+#include <errno.h>
+#include <gpg-error.h>
+
+gpg_error_t update_sm2_hash_md (gcry_md_hd_t md, gcry_mpi_t pkey);
+gpg_error_t update_sm2_hash_value (unsigned char *msg, size_t msglen, gcry_sexp_t s_pkey, unsigned char *result);
+
+#endif /*GNUPG_COMMON_SM2_H*/
diff --git a/common/util.h b/common/util.h
index aa24e39..7b5a1d8 100644
--- a/common/util.h
+++ b/common/util.h
@@ -250,6 +250,9 @@ int openpgp_oidbuf_is_cv25519 (const void *buf, size_t len);
int openpgp_oid_is_cv25519 (gcry_mpi_t a);
int openpgp_oid_is_cv448 (gcry_mpi_t a);
int openpgp_oid_is_ed448 (gcry_mpi_t a);
+#ifdef GPG_USE_SM2
+int openpgp_oid_is_sm2 (gcry_mpi_t a);
+#endif
const char *openpgp_curve_to_oid (const char *name,
unsigned int *r_nbits, int *r_algo);
const char *openpgp_oid_to_curve (const char *oid, int canon);
diff --git a/configure.ac b/configure.ac
index e68b779..3cffc4d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -341,6 +341,16 @@ GNUPG_GPG_DISABLE_ALGO([sha224],[SHA-224 hash])
GNUPG_GPG_DISABLE_ALGO([sha384],[SHA-384 hash])
GNUPG_GPG_DISABLE_ALGO([sha512],[SHA-512 hash])
+AC_ARG_ENABLE([sm2],
+ [AS_HELP_STRING([--enable-sm2], [Enable SM2 support])],
+ [enable_sm2=$enableval],
+ [enable_sm2=no])
+
+if test "x$enable_sm2" = "xyes"; then
+ AC_DEFINE([GPG_USE_SM2], [1], [Define if SM2 support is enabled])
+ AM_CONDITIONAL([GPG_USE_SM2], [test "x$enable_sm2" = "xyes"])
+ CFLAGS="$CFLAGS -DUSE_SM3_PGP"
+fi
# Allow disabling of zip support.
# This is in general not a good idea because according to rfc4880 OpenPGP
diff --git a/g10/keygen.c b/g10/keygen.c
index 6ead599..b6c357e 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -2603,6 +2603,9 @@ ask_curve (int *algo, int *subkey_algo, const char *current)
{ "brainpoolP384r1", NULL, "Brainpool P-384", MY_USE_ECDSADH, 1, 1, 0 },
{ "brainpoolP512r1", NULL, "Brainpool P-512", MY_USE_ECDSADH, 1, 1, 0 },
{ "secp256k1", NULL, NULL, MY_USE_ECDSADH, 0, 1, 0 },
+#ifdef GPG_USE_SM2
+ { "sm2p256v1", NULL, NULL, MY_USE_ECDSADH, 0, 1, 0 },
+#endif
};
#undef MY_USE_ECDSADH
int idx;
diff --git a/g10/misc.c b/g10/misc.c
index 2f4b452..7e60131 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -866,6 +866,11 @@ map_md_openpgp_to_gcry (digest_algo_t algo)
case DIGEST_ALGO_SHA512: return GCRY_MD_SHA512;
#else
case DIGEST_ALGO_SHA512: return 0;
+#endif
+#ifdef GPG_USE_SM2
+ case DIGEST_ALGO_SM3: return GCRY_MD_SM3_PGP;
+#else
+ case DIGEST_ALGO_SM3: return 0;
#endif
default: return 0;
}
@@ -902,6 +907,9 @@ openpgp_md_algo_name (int algo)
case DIGEST_ALGO_SHA384: return "SHA384";
case DIGEST_ALGO_SHA512: return "SHA512";
case DIGEST_ALGO_SHA224: return "SHA224";
+#ifdef GPG_USE_SM2
+ case DIGEST_ALGO_SM3: return "SM3";
+#endif
}
return "?";
}
@@ -1291,7 +1299,10 @@ string_to_digest_algo (const char *string)
if (!*string || *endptr || openpgp_md_test_algo (val))
val = 0;
}
-
+#ifdef GPG_USE_SM2
+ if (val == GCRY_MD_SM3)
+ val = GCRY_MD_SM3_PGP;
+#endif
return val;
}
diff --git a/g10/pkglue.c b/g10/pkglue.c
index f183139..497b555 100644
--- a/g10/pkglue.c
+++ b/g10/pkglue.c
@@ -297,6 +297,11 @@ pk_verify (pubkey_algo_t pkalgo, gcry_mpi_t hash,
{
if (!data[0] || !data[1])
rc = gpg_error (GPG_ERR_BAD_MPI);
+#ifdef GPG_USE_SM2
+ else if (openpgp_oid_is_sm2(pkey[0]))
+ rc = gcry_sexp_build (&s_sig, NULL,
+ "(sig-val(sm2(r%m)(s%m)))", data[0], data[1]);
+#endif
else
rc = gcry_sexp_build (&s_sig, NULL,
"(sig-val(ecdsa(r%m)(s%m)))", data[0], data[1]);
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 06329f6..d59de92 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -34,6 +34,9 @@
#include "options.h"
#include "pkglue.h"
#include "../common/compliance.h"
+#ifdef GPG_USE_SM2
+#include "../common/sm2.h"
+#endif
static int check_signature_end (PKT_public_key *pk, PKT_signature *sig,
gcry_md_hd_t digest,
@@ -622,6 +625,15 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig,
}
gcry_md_final( digest );
+#ifdef GPG_USE_SM2
+ if (openpgp_oid_is_sm2 (pk->pkey[0]))
+ {
+ rc = update_sm2_hash_md (digest, pk->pkey[1]);
+ if (!rc)
+ return rc;
+ }
+#endif
+
/* Convert the digest to an MPI. */
result = encode_md_value (pk, digest, sig->digest_algo );
if (!result)
diff --git a/g10/sign.c b/g10/sign.c
index 05ab5b7..913edb4 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -671,6 +671,10 @@ hash_for (PKT_public_key *pk)
{
unsigned int qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
+#ifdef GPG_USE_SM2
+ if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA && openpgp_oid_is_sm2(pk->pkey[0]))
+ return DIGEST_ALGO_SM3;
+#endif
if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA)
qbytes = ecdsa_qbits_from_Q (qbytes);
qbytes = qbytes/8;
@@ -703,7 +707,6 @@ hash_for (PKT_public_key *pk)
return prefs->value;
}
}
-
return match_dsa_hash(qbytes);
}
else if (openpgp_card_v1_p (pk))
@@ -1869,8 +1872,15 @@ make_keysig_packet (ctrl_t ctrl,
else if (pksk->pubkey_algo == PUBKEY_ALGO_DSA) /* Meet DSA requirements. */
digest_algo = match_dsa_hash (gcry_mpi_get_nbits (pksk->pkey[1])/8);
else if (pksk->pubkey_algo == PUBKEY_ALGO_ECDSA) /* Meet ECDSA requirements. */
- digest_algo = match_dsa_hash
- (ecdsa_qbits_from_Q (gcry_mpi_get_nbits (pksk->pkey[1]))/8);
+ {
+#ifdef GPG_USE_SM2
+ if (openpgp_oid_is_sm2(pk->pkey[0]))
+ digest_algo = DIGEST_ALGO_SM3;
+ else
+#endif
+ digest_algo = match_dsa_hash
+ (ecdsa_qbits_from_Q (gcry_mpi_get_nbits (pksk->pkey[1]))/8);
+ }
else if (pksk->pubkey_algo == PUBKEY_ALGO_EDDSA)
{
if (gcry_mpi_get_nbits (pksk->pkey[1]) > 256)
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index 636d14a..d4aa70f 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -590,6 +590,9 @@ our_md_test_algo (int algo)
case GCRY_MD_SHA384:
case GCRY_MD_SHA512:
case GCRY_MD_WHIRLPOOL:
+#ifdef GPG_USE_SM2
+ case GCRY_MD_SM3:
+#endif
return gcry_md_test_algo (algo);
default:
return 1;
--
2.43.0