544 lines
16 KiB
Diff
544 lines
16 KiB
Diff
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
|